【问题标题】:Kotlin - String interpolation $ vs concatenate using plus-equals +=Kotlin - 字符串插值 $ vs 使用加号 += 连接
【发布时间】:2020-11-05 20:52:09
【问题描述】:
【问题讨论】:
标签:
string
kotlin
string-concatenation
string-interpolation
【解决方案1】:
找出差异的最好方法是查看生成的字节码(我将使用 Kotlin 1.4.10)。
为name += " $someInt"生成的字节码:
ALOAD 0
NEW java/lang/StringBuilder
DUP
INVOKESPECIAL java/lang/StringBuilder.<init> ()V
SWAP
INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
BIPUSH 32
INVOKEVIRTUAL java/lang/StringBuilder.append (C)Ljava/lang/StringBuilder;
ILOAD 1
INVOKEVIRTUAL java/lang/StringBuilder.append (I)Ljava/lang/StringBuilder;
INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String;
ASTORE 0
为name = "$name $someInt"生成的字节码:
NEW java/lang/StringBuilder
DUP
INVOKESPECIAL java/lang/StringBuilder.<init> ()V
ALOAD 0
INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
BIPUSH 32
INVOKEVIRTUAL java/lang/StringBuilder.append (C)Ljava/lang/StringBuilder;
ILOAD 1
INVOKEVIRTUAL java/lang/StringBuilder.append (I)Ljava/lang/StringBuilder;
INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String;
ASTORE 0
结果几乎相同,但在第一种情况下,有一个额外的SWAP 操作,导致第一个append 操作的参数过早加载到堆栈上(在创建StringBuilder 之前,现在他们需要被交换)。
TL;DR
事实证明:
-
StringBuilder 在这两种情况下都会创建
- 在这两种情况下都有 3 个附加(
name、空格和someInt)
- 第二个效果稍微好一点。
【解决方案2】:
语义是等价的,第二个可能更有效,但不完全是因为你给出的原因:它只有一个连接而不是两个。 (第一个先生成" " + someInt,再生成name + (" " + someInt)。)