智能转换
在很多情况下,并不需要显示的使用转换操作符,因为编译器会跟踪不变值的is检查,并在需要时自动转换:
fun demo(x: Any) {
if (x is String) {
print(x.length) // x 被自动转换为String
}
}
编译器可以知道转换是安全的,如果一个类型检查是失败的,并且return:
if (x !is String) return
print(x.length) // x 被自动转换为String
或者是在&&和||中:
// x 会在`||`右边的表达式中转换为String
if (x !is String || x.length == 0) return
// x i会在`&&`右边的表达式中转换为String
if (x is String && x.length > 0) {
print(x.length) // x is automatically cast to String
}
智能转换也可以用在when表达式和while循环。
when (x) {
is Int -> print(x + 1)
is String -> print(x.length + 1)
is IntArray -> print(x.sum())
}
需要注意的是智能转换在编译器不能保证变量在检查和使用期间不会改变时是不会起作用的。更确切的说,智能转换在以下的情况下才适用:
- val局部变量
- val属性,如果属性是private、internal或者类型检查在同一个模块中被声明的地方已经检查过了。智能转换将不再适用重新调用其自定义的getter方法。
- var局部变量,如果变量不会再类型检查和使用期间被修改,并且不会再lambda表达式中被修改。
- var属性,不能被用作智能转换,因为其值可能在任何时候被修改。