Generics
Out Variance
Read a subtype value through a producer of a base type.
variance
`out` marks a generic type parameter that is only produced by the class.
Out Variance
VarianceOut.kt
Replay: real traced execution (multi-file project)
open class Animal(val name: String)
class Dog(name: String) : Animal(name)
class Source<out T>(private val item: T) {
fun get(): T {
return item
}
}
fun readAnimal(source: Source<Animal>): String {
val animal = source.get()
return "animal:${animal.name}"
}
fun main() {
val name = "Rex"
val dogSource: Source<Dog> = Source(Dog(name))
val label = readAnimal(dogSource)
println("name=$name")
println("label=$label")
}
open class Animal(val name: String)
class Dog(name: String) : Animal(name)
class Source<out T>(private val item: T) {
fun get(): T {
return item
}
}
fun readAnimal(source: Source<Animal>): String {
val animal = source.get()
return "animal:${animal.name}"
}
fun main() {
val name = "Milo"
val dogSource: Source<Dog> = Source(Dog(name))
val label = readAnimal(dogSource)
println("name=$name")
println("label=$label")
}
open class Animal(val name: String)
class Dog(name: String) : Animal(name)
class Source<out T>(private val item: T) {
fun get(): T {
return item
}
}
fun readAnimal(source: Source<Animal>): String {
val animal = source.get()
return "animal:${animal.name}"
}
fun main() {
val name = "Nia"
val dogSource: Source<Dog> = Source(Dog(name))
val label = readAnimal(dogSource)
println("name=$name")
println("label=$label")
}
name ← Rex
15fun main() {16 val name→ Rex = "Rex" //@name="Milo", "Nia"17 val dogSource: Source<Dog> = Source(Dog(nameRex))18 val label = readAnimal(dogSource)fun readAnimal(source: Source<Animal>): String
10fun readAnimal(source: Source<Animal>): String {11 val animal = source.get()12 return "animal:${animal.name}"fun get(): T
4class Source<out T>(private val item: T) {5 fun get(): T {6 return item7 }val animal = source.get()
10fun readAnimal(source: Source<Animal>): String {11 val animal = source.get()12 return "animal:${animal.nameRex}"13}label ← animal:Rex
17 val dogSource: Source<Dog> = Source(Dog(name))18 val label→ animal:Rex = readAnimal(dogSource)1920 println("name=$nameRex")21 println("label=$labelanimal:Rex")22}outputname=Rex label=animal:Rex
name ← Milo
15fun main() {16 val name→ Milo = "Milo"17 val dogSource: Source<Dog> = Source(Dog(nameMilo))18 val label = readAnimal(dogSource)fun readAnimal(source: Source<Animal>): String
10fun readAnimal(source: Source<Animal>): String {11 val animal = source.get()12 return "animal:${animal.name}"fun get(): T
4class Source<out T>(private val item: T) {5 fun get(): T {6 return item7 }val animal = source.get()
10fun readAnimal(source: Source<Animal>): String {11 val animal = source.get()12 return "animal:${animal.nameMilo}"13}label ← animal:Milo
17 val dogSource: Source<Dog> = Source(Dog(name))18 val label→ animal:Milo = readAnimal(dogSource)1920 println("name=$nameMilo")21 println("label=$labelanimal:Milo")22}outputname=Milo label=animal:Milo
name ← Nia
15fun main() {16 val name→ Nia = "Nia"17 val dogSource: Source<Dog> = Source(Dog(nameNia))18 val label = readAnimal(dogSource)fun readAnimal(source: Source<Animal>): String
10fun readAnimal(source: Source<Animal>): String {11 val animal = source.get()12 return "animal:${animal.name}"fun get(): T
4class Source<out T>(private val item: T) {5 fun get(): T {6 return item7 }val animal = source.get()
10fun readAnimal(source: Source<Animal>): String {11 val animal = source.get()12 return "animal:${animal.nameNia}"13}label ← animal:Nia
17 val dogSource: Source<Dog> = Source(Dog(name))18 val label→ animal:Nia = readAnimal(dogSource)1920 println("name=$nameNia")21 println("label=$labelanimal:Nia")22}outputname=Nia label=animal:Nia