为什么Kotlin中基于字符串的模板变量没有变化?

时间:2018-07-01 02:05:43

标签: android kotlin

我知道我可以在字符串k表达式中嵌入$aa之类的变量,因此第3行显示结果10。

我认为当我更改aa的值时var k会改变,所以我认为第5行将显示结果15,但实际上它显示了10。为什么?

1  var aa=10
2  var k="$aa"
3  toast(k)  //This is  10

4  aa=aa+5
5  toast(k)   //This is  10, I think it should be 15

6  k="$aa"
7  toast(k)   //This is  15

添加的内容

我认为系统将在以下代码中重新计算第5行,因此我认为新值aa 15将被嵌入到k中,但是实际上,我得到的结果是“ 10 bb”,为什么?

1 var aa=10
2 var k="$aa"
3 toast(k)    //This is  10

4  aa=aa+5
5  k=k+" bb"   //I think system will recalculate, so I think new value 15 will be embed into k
6  toast(k)   //This is  "10 bb", I think it should be "15 bb"

3 个答案:

答案 0 :(得分:2)

字符串是不可变的,引用k指向特定的字符串“ 10”。该字符串由变量aa的内容值组成。

如果将k更改为aa,则需要做一些事情:

  • 字符串是部分可变的(对速度产生重大影响)
  • 几乎每个访问都必须重新计算每个模板化字符串
  • 创建范围必须关闭(请参见“关闭”),以便可以将变量保留在引用中
  • 随后,堆上将有幻影对象。

显示字符串需要大量的计算开销。

要连接两点,示例的最后一行将按您预期的方式进行评估,因为变量现在指向不同的字符串“ 15”,因为变量aa持有的值与以前在字符串处的值不同施工时间。

答案 1 :(得分:1)

写下这一行时:

var k = "$aa"

...赋值右侧的字符串模板将立即求值,分配给k的是模板本身的结果,即文字"10"字符串。该行与您在Java中拥有的相同,并且当然不会随着aa的更新而自动更改:

String k = "" + aa;

String k = String.valueOf(aa);

String k = new StringBuilder().append(aa).toString();

要每次都重新计算该值,可以引入一个局部函数,每次调用一次,以创建新的字符串,并将aa的当前值插入模板:

var aa = 10
fun k() = "$aa" // same as: fun k(): String { return "$aa" }
println(k()) // 10

aa += 5
println(k()) // 15

答案 2 :(得分:1)

Kotlin没有“惰性求值”,并且var k = "$aa"不是函数调用,它只是求值并立即赋值。然后,当您询问var k = "$aa"时,将评估"$aa",并分配k

此后,k将“忘记”它的评估方式,因此您进行aa = aa + 5k无效。

对于“添加的内容”,基于上述相同的思想,k已被“忘记”了其评估方式,分配k = k + " bb"只会直接添加现有的 k(程序级联接,不是存储器级并置),其字符串为“ bb”,而不是用“ $ aa”重新评估k