Kotlin Academy · Pelajaran

Varians pada tapak pengisytiharan

in dan out

Pelajaran 2 daripada 413 langkah

Varians pada tapak pengisytiharan ialah pelajaran Kotlin Academy percuma di CoddyKit. Ini ialah pelajaran 2 daripada 4. Sebanyak 3 pelajaran dalam laluan pembelajaran ini boleh dibaca sepenuhnya secara percuma — selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan praktikal dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Kotlin Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Kotlin Academy merangkumi sejumlah 4 pelajaran.

Masalah Varians

Adakah List<String> sejenis List<Any>? Kadangkala ya, kadangkala tidak. Varians menerangkan cara jenis generik saling berkaitan apabila parameter jenisnya saling berkaitan. Kotlin menggunakan out dan in untuk menyatakan hubungan ini.

Invarian Secara Lalai

Secara lalai, generik adalah invarian: Box<String> BUKAN Box<Any>, walaupun String ialah subjenis kepada jenis sebarang. Ini menghalang operasi yang tidak selamat.

class Box<T>(val value: T)

fun main() {
    val strBox = Box("hi")
    // val anyBox: Box<Any> = strBox // would not compile
    println(strBox.value)
}

Kovarians dengan out

Menandakan parameter jenis sebagai out menjadikannya kovarian: Producer<String> menjadi subjenis kepada Producer<Any>. Jenis itu hanya boleh muncul dalam kedudukan keluaran, iaitu jenis pulangan.

class Producer<out T>(private val item: T) {
    fun produce(): T = item
}

fun main() {
    val strProducer: Producer<String> = Producer("hello")
    val anyProducer: Producer<Any> = strProducer
    println(anyProducer.produce())
}

Mengapa out Selamat

Jika kelas hanya menghasilkan, iaitu memulangkan, T dan tidak pernah menggunakannya, menganggap Producer<String> sebagai Producer<Any> adalah selamat kerana setiap String yang dipulangkannya juga merupakan nilai daripada jenis sebarang.

out dalam Pustaka Standard

List<out E> baca sahaja Kotlin adalah kovarian, sebab itulah List<String> boleh digunakan apabila List<Any> dijangka.

fun printAll(items: List<Any>) {
    items.forEach { println(it) }
}

fun main() {
    val names: List<String> = listOf("Ann", "Bob")
    printAll(names)
}

Kontravarians dengan in

Menandakan parameter jenis sebagai in menjadikannya kontrvarian: Consumer<Any> menjadi subjenis kepada Consumer<String>. Jenis itu hanya boleh muncul dalam kedudukan masukan, iaitu parameter.

class Consumer<in T> {
    fun consume(item: T) {
        println("Consumed $item")
    }
}

fun main() {
    val anyConsumer: Consumer<Any> = Consumer()
    val strConsumer: Consumer<String> = anyConsumer
    strConsumer.consume("hi")
}

Mengapa in Selamat

Pengguna yang menerima Any semestinya boleh menerima String. Jadi, Consumer<Any> boleh digunakan di mana-mana Consumer<String> diperlukan.

Mnemonik PECS

Ingat Producer melanjutkan, Consumer jenis induk, atau dalam istilah Kotlin: out untuk pengeluar, iaitu keluaran, dan in untuk pengguna, iaitu masukan. Jenis yang hanya menghasilkan T menggunakan out; jenis yang hanya menerima T menggunakan in.

Menggabungkan in dan out

Parameter jenis yang digunakan untuk masukan dan keluaran, seperti dalam senarai boleh ubah, mesti kekal invarian. Jenis Function menunjukkan kedua-duanya: parameter ialah in, manakala nilai pulangan ialah out.

fun main() {
    val f: (Number) -> Int = { it.toInt() }
    val g: (Int) -> Number = f
    println(g(3.0.let { Number::class; 5 }))
}

Varians pada Tapak Pengisytiharan Bermaksud Satu Tempat

Varians pada tapak pengisytiharan diisytiharkan sekali sahaja, pada kelas itu sendiri dengan in/out. Setiap penggunaan kelas kemudiannya mendapat varians itu secara automatik, berbeza dengan Java yang memerlukan anda mengulangi kad bebas pada setiap penggunaan.

Memilih in atau out

Tanya: adakah kelas ini hanya menghasilkan T, gunakan out, hanya menerima T, gunakan in, atau melakukan kedua-duanya, lalu kekalkan invarian? Memadankan pengubah dengan peranannya menjadikan jenis generik anda fleksibel dan selamat.

Semakan Pantas

Apakah yang ditunjukkan oleh pengubah out?

Imbas Kembali

Generik secara lalai adalah invarian. Gunakan out untuk kovarians apabila jenis hanya menghasilkan nilai, dan in untuk kontravarians apabila jenis hanya menerima nilai. Ingat, pengeluar menggunakan out dan pengguna menggunakan in. Seterusnya, anda akan menggunakan varians pada titik penggunaan dengan unjuran jenis.

Percuma untuk bermula

Pelajari Kotlin dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
51
Pelajaran
203

Soalan Lazim

Adakah pelajaran “Varians pada tapak pengisytiharan” percuma?

Ya — sebanyak 3 pelajaran dalam laluan pembelajaran Kotlin Academy, termasuk “Varians pada tapak pengisytiharan”, boleh dibaca sepenuhnya secara percuma di web ini. Selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan interaktif dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Kursus Kotlin Academy merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “Varians pada tapak pengisytiharan”?

in dan out Anda berlatih Kotlin Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan Kotlin Academy?

Tiada pengalaman terdahulu diperlukan. Pembelajaran Kotlin Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 2 daripada 4.

Berapa lamakah pelajaran “Varians pada tapak pengisytiharan” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran Kotlin Academy ini?

Ya. Setiap pelajaran Kotlin Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. Fungsi dan kelas generik
  2. Varians pada tapak pengisytiharan
  3. Varians pada tapak penggunaan
  4. Kekangan generik
← Kembali ke Kotlin Academy