价值虚构之后,智能投射到“布尔”是不可能的

第二个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 = trueBoolean并使用printlnAny? 作为参数。

为了使它工作,你必须在你的变量之后添加一个非空声明的调用(!!)。 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? 或者任何具有可变和可空属性的类型都会得到相同的结果。

Interesting Posts