Now i am reading the book which is called "Kotlin in action" and there is the following text:
现在我正在读一本名为《行动中的科特林》的书,书中有这样一段文字:
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.
Here's the example from it:
下面是其中的一个例子:
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))))
}
I tried a bunch of options: changed an object instance and one of its property after is check, used var properties instead of val and also used custom accessors. In all cases is check works great.
我尝试了一堆选项:在检查后更改对象实例和它的一个属性,使用var属性代替val,还使用自定义访问器。在所有情况下,检查工作很好。
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)
}
So what does this text mean ?
那么这篇文章是什么意思呢?
UPD:
更新:
Even in the official kotlin docs it is written that:
甚至在科特林的官方文件中也写道:
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.
but my second example shows that is a lie.
但我的第二个例子表明,这是一个谎言。
更多回答
优秀答案推荐
As the book specified, smart cast is possible if the compiler can guarantee the value didn't change between the check and use. In your case you used a local variable, there is no way anyone can modify this value in the meantime, so the smart cast is possible.
正如书中指定的那样,如果编译器能够保证值在检查和使用之间不发生变化,则智能强制转换是可能的。在您的例子中,您使用了一个局部变量,任何人都不可能同时修改此值,因此智能强制转换是可能的。
It becomes more complicated if we use properties, because then it all depends on the type of the property, how it was implemented, if it belongs to the same module or not, etc. However, the general rule is the same: if the compiler can guarantee no modifications, it will allow smart casts.
如果我们使用属性,情况会变得更加复杂,因为这完全取决于属性的类型、它是如何实现的、它是否属于相同的模块等。然而,一般规则是相同的:如果编译器可以保证不进行任何修改,它将允许智能强制转换。
Update
更新
You seem to confuse properties and local variables. You quote documentation for properties, but there are no properties in your code - only local variables. The article you referenced is clear about the behavior for local variables:
您似乎混淆了属性和局部变量。您引用了有关属性的文档,但代码中没有属性--只有局部变量。您引用的文章清楚地说明了局部变量的行为:
var
local variables - If the variable is not modified between the check and its usage, is not captured in a lambda that modifies it, and is not a local delegated property.
Which is exactly the behavior you observe.
这正是你观察到的行为。
更多回答
I didn't read the book, so I can't say why they chose an example using a local variable. Isn't this the first example, showing what the smart cast even is and not going into more details yet?
我没有读过这本书,所以我说不出他们为什么选择一个使用局部变量的例子。这难道不是第一个例子,展示了什么是聪明的演员阵容,但还没有更多的细节?
excuse me, is parameter e
in their example considered as a local variable ? I though local variables and parameters are different things. In that case can you show an example with is check and without local variables.
请问,在他们的例子中,参数e被认为是局部变量吗?我认为局部变量和参数是不同的东西。在这种情况下,您是否可以展示一个带有IS检查和不带局部变量的示例。
Yes, parameters passed to functions are represented inside them as local variables. Please see my updated answer.
是的,传递给函数的参数在它们内部表示为局部变量。请查看我的更新答案。
If the variable is not modified between the check and its usage
, but in my case it is
如果变量在检查和使用之间没有被修改,但在我的例子中是
We don't smart cast a
or b
here, but value
. If we don't check the type of a local variable, but of a property, e.g.: someObj.value
and this prop wouldn't meet additional requirements, smart cast would not work and we couldn't do e.g.: someObj.value.a
.
我们在这里不是巧妙地选择a或b,而是价值。如果我们不检查局部变量的类型,而是检查属性的类型,例如:ome Obj.Value,而这个道具不能满足额外的要求,则智能强制转换将不起作用,我们也不能执行例如:ome Obj.value.a。
我是一名优秀的程序员,十分优秀!