美文网首页
kotlin基础知识七: kotlin类型系统(type sys

kotlin基础知识七: kotlin类型系统(type sys

作者: 北雁南飞_8854 | 来源:发表于2020-05-07 22:34 被阅读0次

    一、为空性(Nullability)

    Kotlin类型系统的为空性(Nullability)可能帮助你避免NullPointerException错误,比如"An error has occurred: java.lang.NullPointerException"或者"Unfortunately, the application X has stopped",现代语言(包括kotlin在内)的解决方法是把这些问题由运行时错误(runtime errors )转变为编译时错误(compile-time errors)。

    1.1 可空类型(Nullable types)

    Kotlin显式支持nullable types, 这是Kotlin与Java类型系统的第一个、可能也是最重要的不同点。Kotlin中的nullable类型和non-null类型是不同的。
    举例:

    fun strLen(s: String) = s.length
    

    如果调用strLen(null)就会报错。

    >>> strLen(null)
    ERROR: Null can not be a value of a non-null type String
    
    image.png

    注意:nullable类型和non-null类型的对象在运行期是一样的,一个nullable类型并不是对non-null类型的wrapper,所有的checks都是在编译期执行的,因此在kotlin中使用nullable类型是没有运行期开销(runtime overhead)的。

    1.2 Safe call 操作符: “?.”

    表达式s?.toUpperCase()等价于if (s != null) s.toUpperCase() else null.


    image.png

    多个Safe call操作符的链式调用:

    class Address(
        val streetAddress: String, val zipCode: Int,
        val city: String, val country: String
    )
    
    class Company(val name: String, val address: Address?)
    class Person(val name: String, val company: Company?)
    
    fun Person.countryName(): String {
        return company?.address?.country ?: "Unknown"
    }
    
    fun main(args: Array<String>) {
        val person = Person("Dmitry", null)
        println(person.countryName()) //null
    }
    

    1.3 Elvis操作符: “?:”

    含义:为null提供一个默认值,它是Java中三元运算符的一个缩写。
    举个例子:

    fun strLenSafe(s: String?): Int = s?.length ?: 0
    

    等价于Java的

    int strLenSafe(String s) {
        return s != null ? s.length : 0;
    }
    

    也可以在Evlis操作符也可以与抛出异常结合使用。

    class Address(val streetAddress: String, val zipCode: Int,
                  val city: String, val country: String)
    class Company(val name: String, val address: Address?)
    class Person(val name: String, val company: Company?)
    fun printShippingLabel(person: Person) {
        val address = person.company?.address
            ?: throw IllegalArgumentException("No address")
        with (address) {
            println(streetAddress)
            println("$zipCode $city, $country")
        }
    }
    
    fun main(args: Array<String>) {
        val jetbrains = Company("JetBrains", null)
        val person = Person("Dmitry", jetbrains)
        printShippingLabel(person)
    }
    

    输出:
    Exception in thread "main" java.lang.IllegalArgumentException: No address

    1.4 Safe casts操作符:“as?”

    image.png

    举例:
    使用safe cast实现equals方法

    class Person(val firstName:String, val lastName:String) {
        override fun equals(other: Any?): Boolean {
            val otherPerson = other as? Person ?: return false
    
            return otherPerson.firstName == firstName &&
                    otherPerson.lastName == lastName
        }
    }
    

    1.5 Not-null assertions:“!!”

    image.png

    使用非空断言其实是告诉编译器:
    “I know the value isn’t null, and I’m ready for an exception if it turns out I’m wrong.”

    二、类型参数的为空性

    2.1 处理可为空类型的参数

    class MyService {
        fun performAction(): String = "foo"
    }
    
    fun <T> printHashCode(t: T) {
        println("type: " + t + ", hashCode: " + t.hashCode())
    }
    
    fun main(args: Array<String>) {
        val myService: MyService? = null
        printHashCode(myService) //"T" is inferred as "Any?".
    }
    

    输出结果:
    type: null, hashCode: 0

    2.2 处理非空类型的参数

    class MyService {
        fun performAction(): String = "foo"
    }
    
    //“T” can’t be nullable.
    fun <T : Any> printHashCode(t: T) {
        println(t.hashCode())
    }
    
    fun main(args: Array<String>) {
        val myService: MyService? = null
        printHashCode(myService) //compile-error: Type mismatch: inferred type is MyService? but TypeVariable(T) was expected
    }
    

    Any和Any?: the root types

    Any是所有类型的父类型,包括原始类型(primitive type)在内。
    注意Any是一个非空类型(non-nullable type),也就意味着它不能持有null,如果需要的话,需使用Any?。
    举例:

    val answer: Any = 42 //42会被自动装箱(automatically boxed), 因为Any是一个引用类型.
    

    Unit: kotlin中的void

    Nothing

    相关文章

      网友评论

          本文标题:kotlin基础知识七: kotlin类型系统(type sys

          本文链接:https://www.haomeiwen.com/subject/pxhtnhtx.html