Variansi di Lokasi Deklarasi
in dan out
Variansi di Lokasi Deklarasi adalah pelajaran Kotlin Academy gratis di CoddyKit. Ini adalah pelajaran 2 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Kotlin Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Kotlin Academy mencakup 4 pelajaran total.
Masalah Varians
Apakah List<String> merupakan jenis List<Any>? Terkadang ya, terkadang tidak. Varians menjelaskan hubungan antartipe generik ketika parameter tipenya saling berhubungan. Kotlin menggunakan out dan in untuk menyatakannya.
Generik Invarian secara Default
Secara default, generik bersifat invarian: Box<String> BUKAN Box<Any>, meskipun tipe teks merupakan subtipe dari tipe umum. Hal ini mencegah operasi yang tidak aman.
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
Menandai parameter tipe dengan out membuatnya kovarian: Producer<String> menjadi subtipe dari Producer<Any>. Tipe tersebut hanya dapat muncul pada posisi keluaran, yaitu tipe hasil.
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 Aman
Jika sebuah kelas hanya menghasilkan atau mengembalikan T dan tidak pernah menerimanya, memperlakukan Producer<String> sebagai Producer<Any> aman, karena setiap nilai bertipe teks yang dikembalikannya juga merupakan nilai bertipe umum.
out di Pustaka Standar
List<out E> yang hanya dapat dibaca di Kotlin bersifat kovarian. Itulah sebabnya List<String> dapat digunakan ketika List<Any> diharapkan.
fun printAll(items: List<Any>) {
items.forEach { println(it) }
}
fun main() {
val names: List<String> = listOf("Ann", "Bob")
printAll(names)
}Kontravarians dengan in
Menandai parameter tipe dengan in membuatnya kontravarian: Consumer<Any> menjadi subtipe dari Consumer<String>. Tipe tersebut hanya dapat muncul pada posisi masukan, yaitu 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 Aman
Komponen penerima yang menerima nilai bertipe umum tentu dapat menerima nilai bertipe teks. Jadi, Consumer<Any> dapat digunakan di mana pun Consumer<String> diperlukan.
Mnemonik PECS
Ingat: Producer menghasilkan, Consumer menerima supertipe, atau dalam istilah Kotlin: out untuk penghasil (keluaran) dan in untuk penerima (masukan). Tipe yang hanya menghasilkan T menggunakan out; tipe yang hanya menerima T menggunakan in.
Menggabungkan in dan out
Parameter tipe yang digunakan untuk masukan dan keluaran sekaligus, seperti pada daftar yang dapat diubah, harus tetap invarian. Tipe fungsi menunjukkan keduanya: parameternya adalah in, sedangkan hasil pengembaliannya adalah out.
fun main() {
val f: (Number) -> Int = { it.toInt() }
val g: (Int) -> Number = f
println(g(3.0.let { Number::class; 5 }))
}Varians di Deklarasi Berarti Satu Tempat
Varians di deklarasi ditetapkan satu kali pada kelas itu sendiri dengan in/out. Setiap penggunaan kelas tersebut kemudian mendapatkan varians secara otomatis, berbeda dengan Java yang mengharuskan Anda mengulang karakter pengganti di setiap penggunaan.
Memilih in atau out
Tanyakan: apakah kelas ini hanya menghasilkan T (gunakan out), hanya menerima T (gunakan in), atau melakukan keduanya (biarkan invarian)? Menyesuaikan pengubah dengan perannya membuat tipe generik Anda fleksibel dan aman.
Pemeriksaan Singkat
Apa yang ditunjukkan oleh pengubah out?
Ringkasan
Generik bersifat invarian secara default. Gunakan out untuk kovarians ketika suatu tipe hanya menghasilkan nilai, dan in untuk kontravarians ketika tipe tersebut hanya menerima nilai. Ingat, penghasil menggunakan out dan penerima menggunakan in. Selanjutnya, Anda akan menerapkan varians pada titik penggunaan dengan proyeksi tipe.
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Variansi di Lokasi Deklarasi” gratis?
Ya — teks lengkap “Variansi di Lokasi Deklarasi” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Kotlin Academy, upgrade ke CoddyKit PRO. Kursus Kotlin Academy mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Variansi di Lokasi Deklarasi”?
in dan out Kamu berlatih Kotlin Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai Kotlin Academy?
Tidak diperlukan pengalaman sebelumnya. Kotlin Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 2 dari 4.
Berapa lama pelajaran “Variansi di Lokasi Deklarasi” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran Kotlin Academy ini?
Ya. Setiap pelajaran Kotlin Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Fungsi dan Kelas Generik
- Variansi di Lokasi Deklarasi
- Variansi di Lokasi Penggunaan
- Batasan Generik