• Kotlin学习与实践 (十)Kotlin的可空性


    可空类型

    * 类型就是数据的分类。决定了该类型可能的值,以及在该类型值上可以完成的操作。

    * 与Java不同,Kotlin对可空类型的显示的支持。可空类型是Kotlin类型系统中帮助避免NullPointException错误的特性。
    * 这是一种指出你的程序中那些变量和属性允许为null的方式。

    * 可空类型和非可空类型的对象在运行时没有什么区别,可空类型并不是非空类型的包装。所有检查都是在编译时期,所以Kotlin的可空类型并不会在运行时带来额外的开销。
    先来看看Java中的空指针是怎么造成的
    
    
    private int stringLen(String s){
        retrun s.length
    }
    
    
    

    当传入的参数s为null的时候就会发生空指针异常、。

    
    
    * 使用Kotlin声明同样的方法不接收可能为null的参数,因为当如果传入可能会null的参数在编译器就会被标记成错误。
    * 这样就保证了strLen函数永远不会在运行的时候抛出NullPointException
    
    
    fun strLen(s: String) = s.length //Kotlin默认s是不可为null的参数如果你传入一个可能为null参数,编译的时候就会报错
    
    
    
    
    
    
    

      如果你想要声明一个接收参数可能为null的参数,就需要将这个参数声明为可空类型的参数,而可控类型的参数声明起来也特别简单,只需要咋参数的类型之后加上?

    
    
    * ?可以加载任意类型的后面来表示这个类型的变量可以存储null引用。如String? Int? MyCustomType?
    * Type ? = Type or null
    * 没有问号的类型表示这种类型的变量不能存储为null.这说明说有的常见类型都是默认为非空的,除非显示地把它标记为可空的
    * 可空类型的变量不能直接调用其方法、不能把它赋值给费空类型的变量、也不能把可空类型的值传递给拥有非空类型的参数的函数。
    * 再与null 进行比较之后,编译器就会记住,并且在这次比较发生的作用域内把这个值当错非空来对待
    
    
    fun nullAbleStrLen(s: String?): Int = if (null != s) s.length else 0
    
    
    

     安全调用符 

    * Kotlin提供了一种非常有用的工具:安全调用运算符"?"
    * 它允许你把一次对null的检查和一次方法调用合并成一个操作。例如:s?.toUpperCase() 等同于 if(s!=null) s.toUpperCase() else null
    * 如果你试图调用一个非空值的方法,这次方法调用就会被正常执行。但是如果是null 这次调用就不会发生,而整个表达式的值就为null
    fun printAllCaps(s: String?) {
        //这里要注意 因为后面的表达式返回值可能为空,前面的对象类型声明的时候就要声明成可空类型
        val allCaps: String? = s?.toUpperCase()
        println(allCaps)
    }
    * 安全调用不光可以调用方法,也能用来访问属性
    * Kotlin 支持多个安全调用链接再一起使用
    fun managerName(employee: Employee): String? = employee?.name
    
    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 { val country = this.company?.address?.country return if (null != country) country else "Unknown" }

     Elvis 运算符“?:”

    * Elvis 运算符“?:”
    * Kotlin 有方便的运算符来提供null的默认值。它被称作Elvis运算符(或 null合并运算符) -> ?:
    *
    * Elvis运算符接收两个运算数,如果第一个运算数不为null,运算结果就是第一个运算数,如果第一个运算数为null,运算结果就是第二个运算数
    
    
    fun foo(s: String?): String {
        val t: String = s ?: " "
        return t
    }
    
    * Elvis运算符经常和安全调用运算符一起使用,用一个值代替对null对象调用方法时返回的null
    fun strLenSafe(s: String?): Int = s?.length ?: 0
    * 上面获取countryName的方法就可以使用Elvis进一步简化
    fun Person.getCountryName(): String = this.company?.address?.country ?: "Unknown"
    
    * Kotlin中 Elvis和return 、 throw 表达式结合再一起使用会更加好使
    fun printShippingLabel(person: Person) {
        val address = person?.company?.address ?: throw IllegalArgumentException("No address")
        with(address) {
            println(streetAddress)
            println("$zipCode $city $country")
        }
    }
    

     安全转换 "as?"

    * 常规的as运算符和Java中的类型转换一样转换对象的类型,如果被转换的值不是你试图转化的类型,就会抛出ClassCastException。Kotlin提供了一种安全的类型转化操作 as?
    * as?运算符尝试把值转换成指定的类型,如果值不是合适的类型就返回null ,经常会和Elvis “?:” 一起使用。
    class Person1(val firstName: String, val lastName: String) {
        override fun equals(other: Any?): Boolean {
            //类型检查如果不匹配就返回false
            val otherPersion1 = other as?Person1 ?: return false
            //安全检查之后变量会被只能转换为Person1类型
            return otherPersion1.firstName == firstName && otherPersion1.lastName == lastName
        }
    
        override fun hashCode(): Int {
            return firstName.hashCode() * 37 + lastName.hashCode()
        }
    }
    

     非空断言 “!!”

    * 非空断言是Kotlin提供的一种简单直率的处理可空类型值的工具。
    * 它使用双叹号表示,可以把任何值转化为非空类型,如果要转换的值是null,则会抛出NullPointException异常
    fun ignoreNulls(s: String?) {
        val sNotNull: String = s!!
        println(sNotNull)
    }
    //注意当使用!!并且它的结果是异常时,异常调用栈的跟踪信息只会表明异常发生在哪一行,不会表明异常时由那个值引起的,所以尽量避免在一行使用多个非空断言
    // person!!.company!!.address!!.name 出现异常的时候不好查找引起的对象
     
  • 相关阅读:
    [WWF]相关资料整理
    [CSharp]经常遇到字符编码转换的问题
    [BizTalk]BizTalk Server 2004的监控和管理
    [Linux]删除目录
    [BizTalk]好用的BizTalk管理工具
    [JWF]使用脚本访问ActiveDirectory(一)ADODB
    [BizTalk][Why]持久化数据库的状态时出现异常
    [BizTalk]关于BizTalk中的命名规则
    FTP连接
    [导入]跟踪BTSWebSvcWiz.exe的执行过程
  • 原文地址:https://www.cnblogs.com/mauiie/p/kotlin_null.html
Copyright © 2020-2023  润新知