Kotlin Academy · บทเรียน

ฟังก์ชัน Generic และข้อจำกัดชนิดด้วย where

เขียนฟังก์ชัน generic ที่มีข้อจำกัดชนิดเดียวและหลายข้อ

บทเรียน 1 จาก 413 ขั้นตอน

ฟังก์ชัน Generic และข้อจำกัดชนิดด้วย where เป็นบทเรียน Kotlin Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Kotlin Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Kotlin Academy มีบทเรียนทั้งหมด 4 บทเรียน

พื้นฐานฟังก์ชันเจเนอริก

ฟังก์ชันเจเนอริกใช้พารามิเตอร์ชนิดข้อมูลในวงเล็บแหลมที่อยู่ก่อนชื่อฟังก์ชัน พารามิเตอร์ชนิดข้อมูลสามารถนำไปใช้ในชนิดของพารามิเตอร์และชนิดผลลัพธ์ได้

fun <T> identity(value: T): T = value
fun <T> listOf2(a: T, b: T): List<T> = listOf(a, b)
fun main() {
    println(identity(42))       // 42
    println(identity("hello"))  // hello
    println(listOf2(1, 2))      // [1, 2]
}

ขอบเขตบนด้วยข้อจำกัด :

จำกัดพารามิเตอร์ชนิดข้อมูลด้วยขอบเขตบนโดยใช้ : ชนิดข้อมูลนั้นต้องเป็นชนิดย่อยของขอบเขตที่กำหนด

fun <T : Comparable<T>> max(a: T, b: T): T = if (a >= b) a else b
fun main() {
    println(max(3, 7))          // 7
    println(max("apple", "banana")) // banana
    // max(listOf(1), listOf(2)) // error: List is not Comparable
}

ขอบเขตบนที่เป็นค่าว่างได้

ขอบเขตบนเริ่มต้นคือ Any? (เป็นค่าว่างได้) ใช้ T : Any เพื่อไม่อนุญาตให้เป็นค่าว่าง

fun <T : Any> notNull(value: T?): T {
    return value ?: throw IllegalArgumentException("Value is null")
}
fun main() {
    println(notNull("hello"))  // hello
    try { notNull(null) } catch (e: Exception) { println(e.message) }
}

ข้อจำกัดหลายรายการด้วย where

ใช้ประโยค where เพื่อใช้ข้อจำกัดหลายรายการกับพารามิเตอร์ชนิดข้อมูลเดียว

fun <T> process(item: T): String
        where T : Comparable<T>, T : CharSequence {
    return "Length=${item.length}, sorted=${item > "a"}"
}
fun main() {
    println(process("kotlin")) // Length=6, sorted=true
    // process(42) // error: Int doesn't implement CharSequence
}

where กับคลาส

ประโยค where ยังใช้กับพารามิเตอร์ชนิดข้อมูลระดับคลาสได้ด้วย

class SortedContainer<T>(private val items: MutableList<T> = mutableListOf())
        where T : Comparable<T>, T : Any {
    fun add(item: T) { items.add(item); items.sort() }
    fun top(): T? = items.lastOrNull()
}
fun main() {
    val c = SortedContainer<Int>()
    c.add(5); c.add(2); c.add(8)
    println(c.top()) // 8
}

ฟังก์ชันส่วนขยายแบบเจเนอริก

ฟังก์ชันส่วนขยายสามารถมีพารามิเตอร์ชนิดข้อมูลได้เช่นกัน ทำให้ใช้งานกับชนิดข้อมูลเจเนอริกเฉพาะได้

fun <T : Comparable<T>> List<T>.second(): T? {
    return if (size >= 2) this[1] else null
}
fun main() {
    println(listOf(10, 20, 30).second()) // 20
    println(listOf("a").second())        // null
}

พารามิเตอร์ชนิดข้อมูลในตำแหน่งผลลัพธ์

ฟังก์ชันเจเนอริกสามารถอนุมานชนิดข้อมูลจากบริบทได้ จึงไม่จำเป็นต้องระบุอาร์กิวเมนต์ชนิดข้อมูลอย่างชัดเจนที่จุดเรียกใช้

fun <T> MutableList<T>.popOrDefault(default: T): T {
    return if (isEmpty()) default else removeAt(lastIndex)
}
fun main() {
    val list = mutableListOf(1, 2, 3)
    println(list.popOrDefault(0)) // 3
    println(list.popOrDefault(0)) // 2
    println(mutableListOf<Int>().popOrDefault(-1)) // -1
}

เครื่องมือเจเนอริกที่ใช้ซ้ำได้

ฟังก์ชันเจเนอริกทำให้ฟังก์ชันช่วยสามารถใช้ซ้ำกับชนิดข้อมูลต่าง ๆ ได้โดยไม่ต้องเขียนโค้ดซ้ำ

fun <T> Iterable<T>.firstOrElse(default: T): T = firstOrNull() ?: default
fun <T, R : Comparable<R>> Iterable<T>.maxByOrElse(selector: (T) -> R, default: T): T =
    maxByOrNull(selector) ?: default
fun main() {
    println(listOf<String>().firstOrElse("fallback")) // fallback
    println(listOf("a","bbb","cc").maxByOrElse({ it.length }, "")) // bbb
}

การฉายแบบดอกจันเทียบกับไวลด์การ์ดที่มีขอบเขต

เปรียบเทียบการใช้พารามิเตอร์ชนิดข้อมูลที่มีขอบเขต ซึ่งมีประโยชน์เมื่อต้องสร้างหรือรับค่า T กับการฉายแบบดอกจัน ซึ่งใช้เมื่อไม่ทราบชนิดข้อมูล

fun <T : Number> sumList(list: List<T>): Double =
    list.sumOf { it.toDouble() }
// Star projection: read-only, type unknown
fun printAll(list: List<*>) = list.forEach { println(it) }
fun main() {
    println(sumList(listOf(1, 2, 3)))    // 6.0
    printAll(listOf("a", 1, true))       // a, 1, true
}

การสลับคู่แบบเจเนอริก

ฟังก์ชันเจเนอริกที่เรียบง่ายแต่ช่วยให้เห็นภาพ ซึ่งสลับลำดับส่วนประกอบของคู่

fun <A, B> Pair<A, B>.swap(): Pair<B, A> = Pair(second, first)
fun main() {
    val pair = Pair("hello", 42)
    val swapped = pair.swap()
    println(swapped) // (42, hello)
}

ภาคปฏิบัติ: ตัวแยกค่าผลลัพธ์แบบเจเนอริก

ใช้เจเนอริกที่มีขอบเขตเพื่อเขียนฟังก์ชันช่วยที่แปลงค่าใน Result<T> ด้วยการแปลงที่ระบุชนิดข้อมูล

fun <T : Any, R : Any> Result<T>.mapNotNull(transform: (T) -> R?): Result<R> {
    return fold(
        onSuccess = { v ->
            val r = transform(v)
            if (r != null) Result.success(r) else Result.failure(NoSuchElementException())
        },
        onFailure = { Result.failure(it) }
    )
}
fun main() {
    val r = Result.success("123")
    val n = r.mapNotNull { it.toIntOrNull() }
    println(n) // Success(123)
}

ตรวจสอบความเข้าใจ

คุณใช้ข้อจำกัดหลายรายการกับพารามิเตอร์ชนิดข้อมูลหนึ่งรายการได้อย่างไร

สรุปทบทวน

ฟังก์ชันเจเนอริกใช้พารามิเตอร์ชนิดข้อมูลเพื่อเขียนโค้ดที่ใช้ซ้ำได้และปลอดภัยด้านชนิดข้อมูล ใช้ : เพื่อกำหนดขอบเขตเดียว หรือใช้ where สำหรับหลายขอบเขต คอมไพเลอร์ Kotlin จะตรวจสอบข้อจำกัดเหล่านี้ที่จุดเรียกใช้

เริ่มต้นได้ฟรี

เรียนรู้ Kotlin ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
51
บทเรียน
203

คำถามที่พบบ่อย

บทเรียน “ฟังก์ชัน Generic และข้อจำกัดชนิดด้วย where” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “ฟังก์ชัน Generic และข้อจำกัดชนิดด้วย where” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Kotlin Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Kotlin Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “ฟังก์ชัน Generic และข้อจำกัดชนิดด้วย where”

เขียนฟังก์ชัน generic ที่มีข้อจำกัดชนิดเดียวและหลายข้อ คุณปฏิบัติ Kotlin Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Kotlin Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Kotlin Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน

บทเรียน “ฟังก์ชัน Generic และข้อจำกัดชนิดด้วย where” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Kotlin Academy นี้ได้ไหม

ได้ บทเรียน Kotlin Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. ฟังก์ชัน Generic และข้อจำกัดชนิดด้วย where
  2. ความแปรผัน ณ จุดประกาศ: in และ out
  3. Star Projection และการใช้ *
  4. การลบชนิดและพารามิเตอร์ชนิด reified
← กลับไปที่ Kotlin Academy