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

name
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")
}
  1. 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)
  2. fun readAnimal(source: Source<Animal>): String

    10fun readAnimal(source: Source<Animal>): String {11    val animal = source.get()12    return "animal:${animal.name}"
  3. fun get(): T

    4class Source<out T>(private val item: T) {5    fun get(): T {6        return item7    }
  4. val animal = source.get()

    10fun readAnimal(source: Source<Animal>): String {11    val animal = source.get()12    return "animal:${animal.nameRex}"13}
  5. 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
  1. name ← Milo

    15fun main() {16    val name→ Milo = "Milo"17    val dogSource: Source<Dog> = Source(Dog(nameMilo))18    val label = readAnimal(dogSource)
  2. fun readAnimal(source: Source<Animal>): String

    10fun readAnimal(source: Source<Animal>): String {11    val animal = source.get()12    return "animal:${animal.name}"
  3. fun get(): T

    4class Source<out T>(private val item: T) {5    fun get(): T {6        return item7    }
  4. val animal = source.get()

    10fun readAnimal(source: Source<Animal>): String {11    val animal = source.get()12    return "animal:${animal.nameMilo}"13}
  5. 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
  1. name ← Nia

    15fun main() {16    val name→ Nia = "Nia"17    val dogSource: Source<Dog> = Source(Dog(nameNia))18    val label = readAnimal(dogSource)
  2. fun readAnimal(source: Source<Animal>): String

    10fun readAnimal(source: Source<Animal>): String {11    val animal = source.get()12    return "animal:${animal.name}"
  3. fun get(): T

    4class Source<out T>(private val item: T) {5    fun get(): T {6        return item7    }
  4. val animal = source.get()

    10fun readAnimal(source: Source<Animal>): String {11    val animal = source.get()12    return "animal:${animal.nameNia}"13}
  5. 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