据我所知,Java是this post的传值。我来自Java背景我想知道Kotlin用于传递两者之间的值。例如Extensions或Methods等
答案 0 :(得分:22)
每当我听到“传递价值”与“传递参考”Java辩论时,我总是这么认为。我给出的答案:“Java传递引用的副本(按值传递)”(传递引用)。所以每个人都很开心。我会说Kotlin和基于JVM的一样
答案 1 :(得分:15)
语义与Java相同。
在Java中,当你有一个对象的实例,并将它传递给一个方法时,该方法可以改变该对象的状态,并且当方法完成时,这些更改将被应用于该对象。呼叫站点。
同样适用于Kotlin。
答案 2 :(得分:4)
它使用与Java相同的原理。它始终是按值传递的,您可以想象传递了一个副本。对于原始类型,例如Int
显而易见,此类参数的值将被传递到函数中,并且外部变量将不会被修改。请注意,由于Kotlin中的参数的作用类似于val
,因此无法重新分配:
fun takeInt(a: Int) {
a = 5
}
由于无法重新分配a
,因此无法编译此代码。
对于对象来说,这有点困难,但它也是按值调用的。如果使用对象调用函数,则其引用的副本将传递给该函数:
data class SomeObj(var x: Int = 0)
fun takeObject(o: SomeObj) {
o.x = 1
}
fun main(args: Array<String>) {
val obj = SomeObj()
takeObject(obj)
println("obj after call: $obj") // SomeObj(x=1)
}
您可以使用传递给函数的引用来更改实际对象。这将影响您传入的参数。但是,引用本身(即变量的值)将永远不会通过函数调用进行更改。
答案 3 :(得分:3)
在Java基本类型(如int,float,double,boolean)中,它们按值传递给方法,如果您在接收器方法中对其进行修改,则它们不会更改为调用方法。但是,如果属性/变量类型不是基元,则像基元数组或其他类一样,当在方法内部更改它们并将其作为参数接收时,它们也会在调用方方法中更改。 但是对于Kotlin,似乎没有什么是原始的,所以我认为所有内容都是通过引用传递的。
答案 4 :(得分:1)
这可能有点令人困惑。 正确的答案,恕我直言,是所有通过引用传递的,但是不可能进行赋值,所以它类似于在C ++中通过值传递。
请注意,函数参数是常量,即无法分配。
请记住,在Kotlin中没有原始类型。一切都是对象。 当您写时:
var x: Int = 3
x += 10
您实际上创建了一个Int类型的对象,为其分配了值3,并获得了一个名为x的引用或指针。 当你写
x += 10
您将值13的新Int对象重新分配给x。较旧的对象成为垃圾(并被垃圾回收)。
当然,编译器会对其进行优化,在这种特殊情况下不会在堆中创建任何对象,但是从概念上讲,这已得到解释。
那么通过引用函数参数传递是什么意思?
答案 5 :(得分:0)
请记住,我对 Kotlin 很陌生。在我看来,原语是按值传递的,而对象是按引用传递的。
传递给类的原语默认有效,但例如,如果您从列表中传递一个对象,并且该对象发生变化,则类对象也会发生变化。因为,事实上,它是同一个对象。
此外,如果对象从列表中删除,则类对象仍然是参考。所以它仍然可以因其他地方的引用而改变。
下面的例子解释了。您可以here运行它。
fun main() {
val listObjects = mutableListOf(ClassB(), ClassB(), ClassB())
val listPrimitives = mutableListOf(111, 222, 333)
val test = ClassA()
test.ownedObject = listObjects[0]
test.ownedPrimitive = listPrimitives[0]
println("ownedObject: " + test.ownedObject.isEnabled +", ownedPrimitive: " +
test.ownedPrimitive)
listObjects[0].isEnabled = true
println("ownedObject: " + test.ownedObject.isEnabled +", ownedPrimitive: " +
test.ownedPrimitive)
listPrimitives[0] = 999
println("ownedObject: " + test.ownedObject.isEnabled +", ownedPrimitive: " +
test.ownedPrimitive)
}
class ClassA {
var ownedObject: ClassB = ClassB()
var ownedPrimitive: Int = 0
}
class ClassB {
var isEnabled = false
}