Kotlin是否支持像Rust和Swift一样的字符串/数组切片引用?

3
RustSwift中,您可以创建一个数组或字符串的切片,它不会创建元素的新副本,而是使用范围或迭代器给您现有元素的视图,并在内部实现引用对或引用+长度。
Kotlin是否有类似的概念?它似乎对于列表有类似的概念
很难通过Google查找,因为有一个名为“slice”的函数,它似乎复制了元素。我是否完全错误或者缺少什么?
(我知道我可以轻松地解决它。顺便说一句,我没有Java背景。)

1
我自己也是 Kotlin 的新手,但看起来 Kotlin(像 Java 一样)只有 按值传递 - 链接 - clamentjohn
1
@clmno Java总是通过值传递引用 - Boris the Spider
1
List.subList 确实是基于底层 List 的视图 - 因此它将创建一个“切片”而不进行复制。对于 String 没有这样的功能 - subString 将创建底层 char[] 的副本;这是为了避免一个问题而进行的更改,即人们可能会将整个文件读入内存,然后 subString 一小部分 - 小的 String 将保留大的内存。 - Boris the Spider
1
请注意,substring()subSequence()方法都没有明确指定它们不会创建视图或复制数据。由于字符串是不可变的,我认为从开发者的角度来看这并不太重要,我们不应该过于关注。Java不是一种开发者可以完全控制内存布局等方面的语言,这被认为是底层VM/stdlib的实现细节,并且对开发者隐藏。可能会有一种Java的实现方式,例如如果子字符串超过原始字符串的80%则创建一个视图。 - broot
1
当存在可变数据时,情况就开始变得有意义了。实际上,CharBufferCharSequence 的另一种实现,但是它是可变的,并且具有创建视图的 slice() 方法。@hippietrail,如果你可以使用 CharSequence 而不是字符串(它们在某种程度上相似),那么你可以选择使用 CharBuffer。然而,我不确定这是否真的有意义。在大多数情况下,复制数据并不那么糟糕。 - broot
显示剩余5条评论
1个回答

2

我不这样认为。

您可以使用asList将Array转换为列表视图。然后,您已经找到的函数subList像往常一样工作。但是,我不知道是否有ArraysubList等效物。从asList返回的列表是不可变的,因此您不能使用它来修改数组。如果您尝试通过toMutableList使列表可变,它只会创建一个新副本。

fun main() {
    val alphabet = CharArray(26) { 'a' + it }
    println(alphabet.joinToString(", "))

    val listView = alphabet.asList().subList(10, 15)
    println(listView)

    for (i in alphabet.indices) alphabet[i] = alphabet[i].toUpperCase()
    println(alphabet.joinToString(", "))
    // listView is also updated
    println(listView)
}

输出:

a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z
[k, l, m, n, o]
A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z
[K, L, M, N, O]

在Kotlin中,使用列表(或集合)比数组更受欢迎,并且具有比数组更好的泛型和不可变性支持。

如果您需要改变数组,则可能需要自己管理它,传递(对)数组的引用和您关心的索引的IntRange


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接