Upgrade to Pro — share decks privately, control downloads, hide ads and more …

[Lightning] Generic's type variance in Kotlin

[Lightning] Generic's type variance in Kotlin

Alberto Ballano

July 26, 2017
Tweet

More Decks by Alberto Ballano

Other Decks in Technology

Transcript

  1. Invariance Why? List<String> strs = new ArrayList<String>(); List<Object> objs =

    strs; // !!! The cause of the upcoming problem sits here. Java prohibits this!
  2. Invariance Why? List<String> strs = new ArrayList<String>(); List<Object> 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
  3. Invariance Why? List<String> strs = new ArrayList<String>(); List<Object> 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
  4. Invariance Why? List<String> strs = new ArrayList<String>(); List<Object> 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!
  5. Covariance interface Producer<out T> { fun produce(): T } val

    p = object : Producer<String> { override fun produce(): String = "Hello" }
  6. Covariance interface Producer<out T> { fun produce(): T } val

    p = object : Producer<String> { override fun produce(): String = "Hello" } val gp: Producer<Any> = p
  7. Covariance val gp: Producer<Any> = p p.produce() // -> String

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

    gp.produce() // -> Any String <: Any Producer<String> <: Producer<Any> -> You can always read Any from a Producer<String>
  9. Covariance A <: B so, for Producer<? extends T> //

    Producer<out T>: Producer<A> <: Producer<B>
  10. Contravariance interface Consumer<in T> { fun consume(t: T) } val

    c = object : Consumer<Any> { override fun consume(t: Any): Any = print(t) }
  11. Contravariance interface Consumer<in T> { fun consume(t: T) } val

    c = object : Consumer<Any> { override fun consume(t: Any): Any = print(t) } val gc: Consumer<String> = c
  12. Contravariance val gc: Consumer<String> = c c.consume("hello") // <- Any

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

    gc.consume("hello") // <- String String <: Any Consumer<Any> <: Consumer<String> -> You can always write Strings into a Consumer<Any>
  14. Covariance A <: B so, for Consumer<? super T> //

    Consumer<in T>: Consumer<B> <: Consumer<A>