首页 > 解决方案 > 在 kotlin 中字符串是不可变的

问题描述

我正在尝试通过阅读 Kotlin 的文档来学习它。在文档中有一个关于字符串的部分。在该部分中它说:

字符串是不可变的。初始化字符串后,您将无法更改其值或为其分配新值。所有转换字符串的操作都在一个新的 String 对象中返回它们的结果,而原始字符串保持不变。

并试图用一个例子来证明这一点:

fun main() {
    val str = "abcd"
    println(str.uppercase()) // Create and print a new String object
    println(str) // the original string remains the same
}

我对上面写着的部分有疑问:

初始化后字符串的值不能改变。

但是当我更改为时valvar我可以轻松更改字符串的值。

那么文档中说字符串的值不能改变是什么意思呢?我们知道这val使得变量不可变,而不仅仅是字符串。

标签: stringkotlin

解决方案


但是当我更改为时valvar我可以轻松更改字符串的值。

不,你不能轻易做到这一点。假设你有:

var str = "foo"

这不会改变字符串的值"foo"

str = "bar"

您只是获取另一个实例String并将其放入 propertystr中。

请注意,“字符串”和“属性”之间存在差异。“字符串”是指String您通过执行创建的类的实例"foo"。该实例是不可变的。你不能对它做任何事情来使同一个实例具有与 f、o、o 不同的字符序列。这是因为String该类没有提供执行此操作的公共成员,这就是文档说“String不可变”时所指的内容。

另一方面,“属性”是str你声明的那个var str = ...,它可变的。它存储Strings 的实例,您可以更改它存储的实例。但是一旦创建了字符串,您就不能更改它们本身。

将此与列表进行比较。List是不可变的,但你仍然可以这样做:

var myList: List<Int> = listOf(1, 2, 3)

现在假设您要删除列表中的所有 3。您必须创建一个新列表:

// "filter" creates a new list
myList = myList.filter { it != 3 }

因为List是不可变的,并且它没有任何方法可以在不创建新列表的情况下执行此操作。但是,如果myList是 a MutableList,您可以这样做:

// this does not create a new list
myList.removeIf { it == 3 }

虽然没有MutableString:)


推荐阅读