Kotlin学习(5)类型系统

时间:2022-03-04 15:46:30

可空性(避免空指针异常)

/*
*这个函数的参数代表传入一个String类型变量的实例,这代表它不可以为空
*/
fun a(str:String){
    println(str)
}

//这样调用a()会在编译期就显示错误,因为a()的参数不可以是null
>>>a(null)  //这会报错

/*
*我们可以使用 ?来手动的标注哪些变量可以为空值
*/
fun a(str:String?){
    println(str)
}

/*
*一旦某个变量被标注为可空,那么这个变量将不能使用一些方法,如.length()
*/
fun a(str:String?){
    println(str.length) //会报错
}

/*
*可以使用if来判断,这样编译器会根据上下文来得知变量不为空,但是代码会冗长
*/
fun a(str:String?){
    if(str!=null){
        println(str.length) //会报错
    }
}

/*
*安全调用运算符“ ?. ”,如果str!=null,那么会正确调用str的length方法;如果str为空,那么调用不会成立,整个表达式的值为null,所以打印null
*/
fun a(str:String?){
    println(str?.length)
}

/*
*Elvis运算符 “ ?: ” 如果对象为null时,用冒号后的值代替原本的值
*/
fun a(str:String?):Int{
       //若不为空,返回字符串长度,若为空,返回-1
    return str?.length?:-1
}

安全转换 " as? "

/*
*尝试把值转换成给定的类型,如果不合适,则返回null
*/
fun a(str:String?):Int{
    println(str as? Int)
    return 0
}
>>>a("1")
null

非空断言" !! "

  断言一个数据是非空的,如果是空值,就抛空指针异常。

let函数

/*
*如果str是非空的,那么调用lambda中的代码块
*如果是null,那么什么也不会发生
*/
fun a(str:String?):Int{
    str?.let { 
        println(str.length)
    }
    return 0
}

延迟初始化 lateinit

/*
*在一个类声明一个属性,如果它需要在其他方法中单独初始化,可以声明一个可空类型变量使它等于null,但是这样每次使用这个变量都需要判断空值。
*另一个方法是使用lateinit延迟初始化属性
*/
class A{
    lateinit var name:String

    fun a1(){
        print(name)  //这里可以直接使用,不需要空值判断。如果为null,那么会报错----lateinit property name has not been initialized
    }   
}

 

Kotlin中的数据类型

  kotlin中的Int同样可以调用方法,就像Java中的包装类那样。但Java中存在基本数据类型是因为 数值类型的保存速度 比引用类型的保存速度要快。

  所以kotlin中并没有将Int之类的类型完全等于Java中的包装类。

  kotlin在编译时,会尽量将数值变量编译成数值类型,如果数值变量被“?”指定为可空,或者是作为集合的参数,那么将会被编译成包装类。

Any 根类型

  Java中的Object类型是所有引用类型(除八种基本数据类型)的父类。

  在Kotlin中,与之想类似的是Any类型。

  但有一些不同的地方,Any是所有非空类型的超类,其包括Int,Boolean等。而可空类型则可以用“Any?”。

Unit:Kotlin中的Void

  Java中的方法如果没有返回值,则使用void修饰。Kotlin中与之对应的是Unit。

  方法中的Unit可以省略,但如果作为参数传入则不能省 fun a(value:Int -> Unit){ } .

返回值类型为nothing的方法代表这个方法永远不能正常返回,如一个死循环的方法

基本数据类型的数组使用像IntArray这样的特殊类来表示,它的参数会被编译成数值类型