价值虚构之后,智能投射到“布尔”是不可能的
第二个println错误:
智能投射到'布尔'是不可能的,因为'r.isSquare'是一个可变的属性,可以在这个时候改变
fun main(args: Array<String>) { val r: Rectangle = Rectangle(5,5) println(r.isSquare) r.isSquare = true println(r.isSquare) // error but works with println(r.isSquare?:false) } data class Rectangle(var height: Int, var width: Int){ var isSquare: Boolean? = null }
如果它是空的,它会像第一个println一样打印null,为什么我必须这样做呢?
编辑2
感谢所有的答案,我现在明白了:首先是println
println(message: Any?)
第二个println是
println(message: Boolean)
因为r.isSquare = true使编译器信任isSquare是布尔,不再是布尔?
EDIT2
这里是我如何处理编译器来保持信任isSquare是布尔?
fun main(args: Array<String>) { val r: Rectangle = Rectangle(5, 5) println(r.isSquare) r.isSquare = true as Boolean? // if no cast, he will try wrong println signature println(r.isSquare) } data class Rectangle(var height: Int, var width: Int){ var isSquare: Boolean? = null }
由于r.isSquare
是一个可变属性,编译器无法在空检查后智能地将其转换为非null属性。
你可以使用let
:
r.isSquare.let { println(it) }
let
r.isSquare
的值只读取一次,并提供与lambda内部相同的值。 所以你不必使用?
或!!
甚至在空检查之后访问布尔值。
从Kotlin规范 :
该语言使用关于前面检查的信息为null,检查类型(is,!is),安全调用操作符(?)和Nothing返回表达式来推断有关变量类型的附加信息(超出了初始化程序明确指定或推断的他们的声明),可能在某些方面甚至是表达方面更为具体。 然后使用这些信息对这些表达式进行更广泛的操作,并选择更具体的过载。
fun main(args: Array<String>) { var x : Any x = "" x.toUpperCase() // OK, smart cast to String }
第一个println
使用这个println(message: Any?)
由于您接下来将isSquare
分配为true
,因此编译器尝试将isSquare
转换为Boolean
类型,然后尝试打印。 但它不能聪明的投射,因为属性是一个可变的类型。
如果你删除这行, r.isSquare = true
,那么编译器不会试图将其r.isSquare = true
为Boolean
并使用println
和Any?
作为参数。
为了使它工作,你必须在你的变量之后添加一个非空声明的调用(!!)。 r !! isSquare或r.isSquare!
fun main(args: Array<String>) { val r: Rectangle = Rectangle(5,5) println(r.isSquare) r.isSquare = true println(r.!! isSquare) } data class Rectangle(var height: Int, var width: Int) { var isSquare: Boolean? = null }
由于isSquare是一个可变属性(var)。 这意味着你在哪里写了一个值,然后你读了它,在另一个线程可以修改它,并因此得到一个NPE。
r.isSquare = true //Another thread set r.isSquare = null println(r.isSquare) // you get a null pointer exception
每次使用可空变量时,都必须检查属性的可空性。
因为Android中的println()函数不支持布尔?,而布尔? kotlin的可变属性不能由Kotlin的智能转换自动解包。
试试字符串? 还是Int? 或者任何具有可变和可空属性的类型都会得到相同的结果。