空类型和智能类型转换
字符串被设定为不能为null。例如:
fun getName():String{
return null;
}
上面这样的代码段编译不会被通过,提示字符串不能被返回空值。
因此,下面一小段代码是空指针安全的。
fun main(args:Array<String>){
println(getName().length)
}
如果要定义可以返回空值的字符串
fun getName():String?{
return null;
}
写成这样再调,有可能报空指针,这样就要对结果进行空指针判断。
fun getName():String?{//返回值可以为空
return null;
}
fun main(args:Array<String>){
val name = getName();
if (name == null){
println("name is invalid")
}else{
println(name.length)
}
}
在kotlin中可以简写成以下代码
fun main(args:Array<String>){
val name = getName();
println(name?.length)//判断name是不是为空,如果不为空返回长度,为空则返回null
}
或者使用Elvis 操作符(?:)
用法:<结果> = <表达式1> ?: <表达式2> 如果表达式1为null,则返回表达式2的内容,否则返回表达式1。请注意,当且仅当左侧表达式1为空时,才会对右侧表达式求值。
fun main(args:Array<String>){
val name :String= getName()?:return;//getName()为空么?如果为空就return,不为空则把值赋给name
println(name.length)
}
空类型的智能判断:
- val notNull:String = null //错误,该变量不能为空
- val nullable:String ?= null //正确,此时该字符串或变量可以为空
- notNull.length // 正确,不为空的值可以直接使用
- nullable.length // 错误,可能为空的时候,不可以直接获取长度
- nullable!!.length // 正确,!!运算符强制认定nullable不可为空
- nullable?.length //正确,用elvis运算符判断,若nullable变量为空时返回null
智能类型转换 - .is和!is操作符(Operators) 用is或!is操作符来检查对象类型是否符合要求:
val parent:Parent = Child()
if(parent is Child){
println(parent.name)
}
if(Child !is Parent){
println(child.name)
}
- 智能转换(Smart Casts)
与java不同,Kotlin不需要显式转换对象类型,对于不可变的值,编译器可以用is检查类型,自动加入类型转换代码
fun demo(x: Any) {
if (x is String) {
print(x.length) //编译器自动把x转换为String类型
}
}
识别反向检查类型!is操作符,自动插入类型转换代码:
if (x !is String) return
print(x.length) //编译器自动把x转换为String类型:
// ||右侧, x自动转换为String类型
if (x !is String || x.length == 0) return
// &&右侧, x自动转换为String类型
if (x is String && x.length > 0) {
print(x.length) // x 自动转换为字符串
}
//智能转换(smart casts)也用于when表达式和while循环
when (x) {
is Int -> print(x + 1)
is String -> print(x.length + 1)
is IntArray -> print(x.sum())
}
智能转换的适用条件:必须保证变量在类型检查is/!is操作符和变量使用之间不可改变。
val局部变量:总是适用。
val属性:适用于private或internal,或者类型检查is/!is在声明属性的同一模块中执行;不适用于open的属性,或者具有自定义getter的属性。
var局部变量:适用于变量在类型检查和使用之间没有修改,且不在修改它的lambda中捕获!
var属性:不适用(因为该变量可随时被修改)
- 不安全转换-操作符as
如果类型不可能转换,转换操作符会抛出异常,称为不安全转换,中缀操作符as会出现不安全转换,例如:
val y = null
//kotlin类型默认不能为空(null),as会抛出异常TypeCastException
val x: String = y as String
//必须在转换右边添加?,表示可空(null)类型:
val x: String? = y as String? - 安全(可空)转换-操作符as?
为避免抛出异常,可用安全转换操作符as?,在失败时返回null
val x: String? = y as? String
尽管as?右边是一个非空类型String,但是as?转换失败时返回可空(null)
kotlin中的包就是一个命名空间,包的声明在非注释代码的第一行。
区间(range)
val range:IntRange = 0..1024 // [o,1024]
val range_exclusive:IntRange = 0 until 1024 //[0,1024) = [0,1023]
区间是一个数学上的概念,表示范围,是ClosedRange的子类,IntRange最为常用。
基本写法:
0..100 表示【0,100】的闭区间
0 untile 100 表示【0,100)左闭右开区间
i in 0..100 表示判断i是否在区间【0,100】中
数组表示一系列的对象。
数组的基本写法
val arrayOfInt:IntArray = intArrayOf(1,3,5,7)
val arrayOfChar:CharArray = charArrayOf('H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd', '!')
val arrayOfString:Array<String> = arrayOf("I","am","a","coder")
val arrayOfChairman:Array<ChairMan> = arrayOf(ChairMan("Zhang"), ChairMan("Zhao"), ChairMan("Huang"))
基本操作
print array【i】输出第i个成员
array【i】 = “hello” 给第i个成员赋值
array.length 数组的长度