zoukankan      html  css  js  c++  java
  • 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 出现异常的时候不好查找引起的对象
     
  • 相关阅读:
    node
    github
    [模块] pdf转图片-pdf2image
    python 15 自定义模块 随机数 时间模块
    python 14 装饰器
    python 13 内置函数II 匿名函数 闭包
    python 12 生成器 列表推导式 内置函数I
    python 11 函数名 迭代器
    python 10 形参角度 名称空间 加载顺序
    python 09 函数参数初识
  • 原文地址:https://www.cnblogs.com/mauiie/p/kotlin_null.html
Copyright © 2011-2022 走看看