Slide 1

Slide 1 text

Generic Type variance (in Kotlin) The topic that killed my brain

Slide 2

Slide 2 text

Invariance

Slide 3

Slide 3 text

Invariance Why? List strs = new ArrayList();

Slide 4

Slide 4 text

Invariance Why? List strs = new ArrayList(); List objs = strs; // !!! The cause of the upcoming problem sits here. Java prohibits this!

Slide 5

Slide 5 text

Invariance Why? List strs = new ArrayList(); List objs = strs; // !!! The cause of the upcoming problem sits here. Java prohibits this! objs.add(1); // Here we put an Integer into a list of Strings

Slide 6

Slide 6 text

Invariance Why? List strs = new ArrayList(); List objs = strs; // !!! The cause of the upcoming problem sits here. Java prohibits this! objs.add(1); // Here we put an Integer into a list of Strings String s = strs.get(0); // !!! ClassCastException: Cannot cast Integer to String

Slide 7

Slide 7 text

Invariance Why? List strs = new ArrayList(); List objs = strs; // !!! The cause of the upcoming problem sits here. Java prohibits this! objs.add(1); // Here we put an Integer into a list of Strings String s = strs.get(0); // !!! ClassCastException: Cannot cast Integer to String Note: All generic types in Java are invariant!

Slide 8

Slide 8 text

Invariance A <: B so, for List: List

Slide 9

Slide 9 text

Covariance interface Producer { fun produce(): T }

Slide 10

Slide 10 text

Covariance interface Producer { fun produce(): T } val p = object : Producer { override fun produce(): String = "Hello" }

Slide 11

Slide 11 text

Covariance interface Producer { fun produce(): T } val p = object : Producer { override fun produce(): String = "Hello" } val gp: Producer = p

Slide 12

Slide 12 text

Covariance val gp: Producer = p

Slide 13

Slide 13 text

Covariance val gp: Producer = p p.produce() // -> String gp.produce() // -> Any

Slide 14

Slide 14 text

Covariance val gp: Producer = p p.produce() // -> String gp.produce() // -> Any String <: Any Producer <: Producer

Slide 15

Slide 15 text

Covariance val gp: Producer = p p.produce() // -> String gp.produce() // -> Any String <: Any Producer <: Producer -> You can always read Any from a Producer

Slide 16

Slide 16 text

Covariance A <: B so, for Producer // Producer: Producer <: Producer

Slide 17

Slide 17 text

Contravariance interface Consumer { fun consume(t: T) }

Slide 18

Slide 18 text

Contravariance interface Consumer { fun consume(t: T) } val c = object : Consumer { override fun consume(t: Any): Any = print(t) }

Slide 19

Slide 19 text

Contravariance interface Consumer { fun consume(t: T) } val c = object : Consumer { override fun consume(t: Any): Any = print(t) } val gc: Consumer = c

Slide 20

Slide 20 text

Contravariance val gc: Consumer = c

Slide 21

Slide 21 text

Contravariance val gc: Consumer = c c.consume("hello") // <- Any gc.consume("hello") // <- String

Slide 22

Slide 22 text

Contravariance val gc: Consumer = c c.consume("hello") // <- Any gc.consume("hello") // <- String String <: Any Consumer <: Consumer

Slide 23

Slide 23 text

Contravariance val gc: Consumer = c c.consume("hello") // <- Any gc.consume("hello") // <- String String <: Any Consumer <: Consumer -> You can always write Strings into a Consumer

Slide 24

Slide 24 text

Covariance A <: B so, for Consumer // Consumer: Consumer <: Consumer

Slide 25

Slide 25 text

Links https://kotlinlang.org/docs/reference/generics.html#varianc e https://medium.com/@tpolansk/understanding-generics-and- variance-in-kotlin-714c14564c47

Slide 26

Slide 26 text

Thank you Q&A