关于Kotlin smart cast不生效场景的困惑及验证问询
最近我在读《Kotlin in Action》这本书,里面有一段关于Smart Cast的描述:
The smart cast works only if a variable couldn’t have changed after the is check.
When you’re using a smart cast with a property of a class, as in this example, the property has to be a val and it can’t have a custom accessor. Otherwise, it would not be possible to verify that every access to the property would return the same value.
书中给出的示例代码是这样的:
interface Expr class Num(val value: Int) : Expr class Sum(val left: Expr, val right: Expr) : Expr fun eval(e: Expr): Int { if (e is Num) { val n = e as Num return n.value } if (e is Sum) { return eval(e.right) + eval(e.left) } throw IllegalArgumentException("Unknown expression") } fun main(){ println(eval(Sum(Sum(Num(1), Num(2)), Num(4)))) }
为了验证这个限制,我尝试了好几种情况:在is检查后修改对象实例和它的属性、用var属性代替val、还有使用自定义访问器,但所有情况下is检查都正常工作了。
我的测试代码如下:
interface face1 class A(): face1{ var a = 1 get() = field set(value){field = field+value} } class B(): face1{ var b = 1 get() = field set(value){field = field + value} } fun Test(x: face1){ var value = x if(value is A){ value = A() println("hello") value.a = 123 println(value.a) } if(value is B) println(value.b) } fun main(args: Array<String>){ val x: face1 = A() Test(x) }
这就让我有点困惑了,书中这段描述到底是什么意思呢?
更新:
我甚至查了Kotlin官方文档,里面也写着:
Note that smart casts work only when the compiler can guarantee that the variable won't change between the check and its usage.
var properties: Never, because the variable can be modified at any time by other code.
但我的测试例子显然和这个描述不符,这是怎么回事?
备注:内容来源于stack exchange,提问作者VanechikSpace

