Kotlin Notes - 5

发布时间 2023-11-27 23:18:50作者: Otlpy
  1. In Kotlin, the type system distinguishes between references that can hold null (nullable references) and those that cannot (non-nullable references). For example, a regular variable of type String cannot hold null:

    var a: String = "abc" // Regular initialization means non-nullable by default
    a = null // compilation error
    

    To allow nulls, you can declare a variable as a nullable string by writing String?:

    var b: String? = "abc" // can be set to null
    b = null // ok
    print(b)
    
  2. Compiler can check for null in condition:

    val b: String? = "Kotlin"
    if (b != null && b.length > 0) {
       print("String of length ${b.length}")
    } else {
       print("Empty string")
    }
    
  3. Your second option for accessing a property on a nullable variable is using the safe call operator ?.:

    val a = "Kotlin"
    val b: String? = null
    println(b?.length)
    println(a?.length) // Unnecessary safe call
    

    This returns b.length if b is not null, and null otherwise. The type of this expression is Int?.

  4. When you have a nullable reference, b, you can say "if b is not null, use it, otherwise use some non-null value":

    val l: Int = if (b != null) b.length else -1
    

    Instead of writing the complete if expression, you can also express this with the Elvis operator ?::

    val l = b?.length ?: -1
    

    If the expression to the left of ?: is not null, the Elvis operator returns it, otherwise it returns the expression to the right. Note that the expression on the right-hand side is evaluated only if the left-hand side is null.

    Since throw and return are expressions in Kotlin, they can also be used on the right-hand side of the Elvis operator.

    fun foo(node: Node): String? {
        val parent = node.getParent() ?: return null
        val name = node.getName() ?: throw IllegalArgumentException("name expected")
        // ...
    }
    
  5. The not-null assertion operator (!!) converts any value to a non-nullable type and throws an exception if the value is null.

    val l = b!!.length
    
  6. Regular casts may result in a ClassCastException if the object is not of the target type. Another option is to use safe casts that return null if the attempt was not successful:

    val aInt: Int? = a as? Int