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

4. Kotlin Types [kotlin-workshop]

4. Kotlin Types [kotlin-workshop]

Part of https://github.com/jetBrains/kotlin-workshop.

Covers:
- Basic types (primitives)
- Nullable types & Java
- Collections types & Java
- Variance

Recording of this talk (excluding variance):
https://www.youtube.com/watch?list=PLQ176FUIyIUY6UK1cgVsbdPYA3X5WLam5&v=Uizh2WlJtnk

Svetlana Isakova

November 01, 2017
Tweet

More Decks by Svetlana Isakova

Other Decks in Programming

Transcript

  1. public static final int foo() { return 1; } @Nullable

    public static final Integer bar() { return Integer.valueOf(1); } Decompiled Java code
  2. fun foo(): Int = 1 public static final int foo()

    { return 1; } Correspondence between Kotlin and Java types Kotlin code: Decompiled Java code:
  3. public static final Integer bar() { return 1; } Correspondence

    between Kotlin and Java types Kotlin code: Decompiled Java code: fun bar(): Int? = 1
  4. Primitive & wrapper types Kotlin Java Int int Double double

    Boolean boolean Kotlin Java Int? java.lang.Integer Double? java.lang.Double Boolean? java.lang.Boolean
  5. No boxing now log(2017) fun log(any: Any) { println("Value: $any")

    } fun log(i: Int) { println("Value: $i") }
  6. Unit instead of void No meaningful value is returned fun

    f(): Unit { /*...*/ } Two equivalent syntactic forms: fun f() { /*...*/ }
  7. Nothing is different to Unit/void fun fail(message: String): Nothing {


    throw IllegalStateException(message)
 } It means “this function never returns”
  8. “a type that allows only one value and thus can

    hold no information” Unit Nothing “a type that has no values” “the function completes successfully” “the function never completes”
  9. Expressions of Nothing type inline fun TODO(reason: String): Nothing =

    throw NotImplementedError("An operation is not implemented: $reason") val answer: Int = if (timeHasPassed()) { 42 } else { TODO("Needs to be done") }
  10. fun greetPerson(person: Person) { val name: String = person.name ?:

    throw IllegalArgumentException("Name is unspecified") println("Hello, $name!") } Expressions of Nothing type
  11. fun greetPerson(person: Person) { val name = person.name ?: fail("Name

    is unspecified") println("Hello, $name!") } Expressions of Nothing type
  12. fun greetPerson(person: Person) { val name = person.name ?: return

    println("Hello, $name!") } Expressions of Nothing type
  13. val answer = if (timeHasPassed()) { 42 } else {

    fail("Not ready") } fun fail(message: String) {
 throw IllegalStateException(message)
 } Let’s say, fail function returns Unit Int Unit Any : Unit
  14. val answer: Any = if (timeHasPassed()) { 42 } else

    { fail("Not ready") } fun fail(message: String) {
 throw IllegalStateException(message)
 } Int Any Unit Let’s say, fail function returns Unit
  15. val answer = if (timeHasPassed()) { 42 } else {

    fail("Not ready") } fun fail(message: String): Nothing {
 throw IllegalStateException(message)
 } Now, fail returns Nothing
  16. val answer = if (timeHasPassed()) { 42 } else {

    fail("Not ready") } fun fail(message: String): Nothing {
 throw IllegalStateException(message)
 } Int Nothing Now, fail returns Nothing
  17. val answer: Int = if (timeHasPassed()) { 42 } else

    { fail("Not ready") } fun fail(message: String): Nothing {
 throw IllegalStateException(message)
 } Nothing Int Now, fail returns Nothing
  18. Type of null var user = null user = User("svtk")

    val users = mutableListOf(null) users.add(User("svtk")) Error: Type mismatch: inferred type is User but Nothing? was expected Error: Type mismatch: inferred type is User but Nothing? was expected
  19. Type of null var user: Nothing? = null user =

    User("svtk") val users: List<Nothing?> = mutableListOf(null) users.add(User("svtk"))
  20. Specify types explicitly var user: User? = null user =

    User("svtk") val users: List<User?> = mutableListOf(null) users.add(User("svtk")) ✓ ✓
  21. Type? then the code looks like Type And it doesn’t

    really work with generics !! !! !! !! !! !! !! !! !! !! !! !! If
  22. Platform type in error message public class Session {
 public

    String getDescription()
 } val session = Session()
 val description: Boolean = session.description Compiler error: Type mismatch: inferred type is String! but Boolean was expected
  23. Using Java from Kotlin val session = Session()
 val description

    = session.description
 println(description.length) NullPointerException! public class Session {
 public String getDescription() {
 return null;
 }
 }
  24. Different annotations are supported @Nullable @NotNull JetBrains @Nullable @NonNull Android

    @Nullable @CheckForNull JSR-305 @Nullable @CheckForNull FindBugs @NonNull Lombok ...
  25. Using Java from Kotlin public class Session { @Nullable String

    getDescription() { return null; } } val session = Session() val description = session.description println(description.length) compiler error
  26. Type @NotNull @Nullable Type Annotate your Java types - You

    can specify @NotNull as default, and annotate only @Nullable types - All of them???
  27. @MyNonnullByDefault public class Session { public void setDescription(String description) {

    this.description = description; } } @NonNull by default val session = Session() session.setDescription(null) Warning: Expected type doesn’t accept nulls in Java, but the value may be null in Kotlin
  28. @MyNonnullByDefault public class Session { public void setDescription(String description) {

    this.description = description; } } @NonNull by default val session = Session() session.setDescription(null) Error: Null can not be a value of a non-null type String
  29. Specify types explicitly val session = Session() val description: String?

    = session.description println(description?.length) public class Session {
 public String getDescription() {
 return null;
 }
 } ✓
  30. IllegalStateException: session.description must not be null val session = Session()

    val description: String = session.description public class Session {
 public String getDescription() {
 return null;
 }
 } Specify types explicitly
  31. val session = Session() val description: String = session.description println(description)

    Intrinsic checks is generated by the compiler throws an exception if session.description is null Intrinsics.checkExpressionValueIsNotNull( description, "session.description");
  32. Read-only immutable (1, 2, 3) • Read-only interface just lacks

    mutating methods • The actual list can be changed by another reference list mutableList
  33. val mutableList = mutableListOf(1, 2, 3) val list: List<Int> =

    mutableList println(list) // [1, 2, 3] (1, 2, 3) list mutableList (1, 2, 3, 4) mutableList.add(4) println(list) // [1, 2, 3, 4] Read-only immutable
  34. Under the hood fun getNames(): List<String>
 fun getNames(): MutableList<String> 


    java.util.List<String> getNames(); Both functions are compiled to:
  35. Platform type for Java collection collection type of “unknown” mutability

    List<String> (Mutable)List<String!> notation, not syntax type that came from Java
  36. Read-only interfaces improve API object Shop { private val customers

    = mutableListOf<Customer>() fun getCustomers(): List<Customer> = customers } val customers = Shop.getCustomers() customers.add() you can’t shoot yourself in the foot any longer
  37. interface Function1<in P, out R> {
 operator fun invoke(p: P):

    R
 } (Animal) -> Int (Cat) -> Any Animal Cat Int Any in/out on the declaration-site
  38. Just (T) -> R on the call-site inline fun <T,

    R> Iterable<T>.map(
 transform: (T) -> R): List<R> Function1<T, R>