Kotlin - 字符串插值 $ 与使用加等于 +=

问题描述 投票:0回答:2

问题很简单: 这两个版本有什么区别(都初始化了

var name: String
val someInt: Int
)?

name += " $someInt"

name = "$name $someInt"

我还读到字符串插值

$
使用StringBuilder,所以第二个代码应该优先于第一个代码(使用串联)?

string kotlin string-concatenation string-interpolation
2个回答
5
投票

找到差异的最佳方法是查看生成的字节码(我将使用 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;博士

事实证明:

  1. StringBuilder
    在两种情况下都会创建
  2. 两种情况下都有 3 个附加(
    name
    、空格和
    someInt
  3. 第二个稍微有效一些。

0
投票

语义是等效的,第二个可能稍微更有效,但并不完全符合您给出的原因:只有一个串联而不是两个。 (第一个先生成

" " + someInt
,然后生成
name + (" " + someInt)
。)

© www.soinside.com 2019 - 2024. All rights reserved.