kotlin - Kotlin 是 "pass-by-value"还是 "pass-by-refer

据我所知,Java 是来自 this post 的值传递.我来自 Java 背景,我想知道 Kotlin 使用什么来在两者之间传递值。喜欢 Extensions或 Methods等等

最佳答案

每次我听到关于“按值传递”与“按引用传递”Java 辩论时,我总是这么想。我给出的答案是:“Java 传递引用(按引用传递)的副本(按值传递)”。所以大家都很开心。我会说 Kotlin 的功能与基于 JVM 的语言相同。

更新

好的,距离这个答案已经有一段时间了,我认为应该包括一些澄清。正如@robert-liberatore 在评论中提到的那样,我所描述的行为是真实的对象。每当您的方法需要任何对象时,您都可以假设 JVM 在内部将复制对该对象的引用并将其传递给您的方法。这就是为什么有这样的代码

void doSomething(List<Integer> x) {
  x = new ArrayList<Integer>()
}

List<Integer> x = Arrays.asList(1, 2, 3);
doSomething(x);
x.length() == 3

表现得像它一样。您正在复制对列表的引用,因此“重新分配它”对真实对象无效。但是由于您指的是同一个对象,因此修改其内部内容会影响外部对象。

在将属性定义为 final 以实现不变性时,您可能会忽略这一点。您将无法重新分配它们,但没有什么可以阻止您更改其内容

当然,对于您有引用的对象也是如此。在原语的情况下,它不是对包含某物的对象的引用,而是“某物”本身,那么事情就不同了。 Java 仍然会复制整个值(就像它对整个引用所做的那样)并将其传递给方法。但是原语只是值,您不能“修改其内部值”。因此,方法内部的任何更改都不会影响外部值

现在,谈谈 Kotlin

在 Kotlin 中,您“没有”原始值。但是你“确实有”原始类。在内部,编译器将在需要时尝试使用 JVM 原语值,但您可以假设您始终使用 JVM 原语的盒装版本。因此,在可能的情况下,编译器只会复制原始值,而在其他情况下,它将复制对对象的引用。或者用代码

fun aJvmPrimitiveWillBeUsedHere(x: Int): Int = x * 2

fun aJvmObjectWillBeUsedHere(x: Int?): Int = if (x != null) x * 2 else 1

我会说 Kotlin 场景比 Java 更安全,因为它强制它的参数是最终的。所以你可以修改它的内部内容,但不能重新分配它

fun doSomething(x: MutableList<Int>) {
    x.add(2)                  // this works, you can modify the inner state
    x = mutableListOf(1, 2)   // this doesn't work, you can't reassign an argument
}

关于kotlin - Kotlin 是 "pass-by-value"还是 "pass-by-reference"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44515031/

相关文章:

kotlin - 在 Kotlin 中处理可为空或空列表的惯用方式

android - 监听器绑定(bind);找不到二传手

arrays - Kotlin 中的二维 Int 数组

regex - 使用正则表达式在 Kotlin 中进行 URL 解析

kotlin - Kotlin 中的静态数据

android - 更新到 AS 3.0 Canary 6 后 transformClassesWi

java - Kotlin 数据类实现 Java 接口(interface)

kotlin - 在 Kotlin 中带有参数的单例

java - 如何从 Kotlin/Java 中运行 Kotlin-Script (.kts) 文件

java - Gradle 项目 : java. lang.NoClassDefFoundError