智能投射到'Boolean'在价值影响后是不可能的



第二个打印错误:

智能投射到"布尔值"是不可能的,因为"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 一样打印空,为什么我必须这样做?

编辑 2

感谢您的所有回答,我现在明白了: 第一个打印是

println(message: Any?)

第二个打印是

println(message: Boolean)

因为 r.isSquare = true 使编译器信任 isSquare 是布尔值而不是布尔值?

编辑2

以下是我如何处理编译器以保持信任是方形是布尔值吗?

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 检查后将其智能强制转换为非 null 属性。

您可以使用let

r.isSquare.let { println(it) }

let只读取一次r.isSquare的值,它提供的值与 lambda 中的it值相同。因此,即使在 null 检查之后,您也不必使用?!!来访问布尔值。

来自 Kotlin 规范:

该语言使用有关前面检查 null、检查的信息 对于类型(is,!is(,安全呼叫操作员(?.(和无返回 用于推断有关变量类型的其他信息的表达式 (超出从初始值设定项显式指定或推断的 他们的声明(在某些区块中可能更具体,或者 甚至表情。然后,此信息将用于启用更广泛的 对这些表达式进行操作,并选择更具体的重载。

fun main(args: Array<String>) {
var x : Any
x = ""
x.toUpperCase() // OK, smart cast to String
}

第一个println使用此println(message: Any?)

由于接下来要true分配给isSquare,因此当您尝试打印isSquare类型时,编译器会尝试将智能转换为Boolean类型。但它无法智能转换,因为该属性是可变类型。

如果删除行r.isSquare = true,则编译器不会尝试将其智能转换为Boolean,而是使用带有Any?println作为参数。

为了使它工作,您必须在变量后添加一个非空断言调用 (!!(。要么 r!.是方形或r.is广场!!

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 
}

As 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 的智能强制转换自动解包。

尝试 String? 或 Int? 或任何具有可变和可为空属性的类型都会发生同样的事情。

相关内容

  • 没有找到相关文章

最新更新