我正在尝试创建一个交换函数,它接受两个参数,如下所示:
fun swap(a :Int, b:Int) {
}
我这样称呼它:
var a = 10
var b = 5
swap(a,b)
// a should be 5
// b should be 10
问题是,即使我交换了交换函数内的值,它也不会反射(reflect)在调用者的一侧,因为它是作为副本而不是作为引用传递的。
反正有没有将值类型传递给交换函数并允许函数改变它们的能力。
最佳答案
绝对没有办法直接做到这一点。 Kotlin 复制标量类型的值( Double
、 Float
、 Boolean
、 Int
等)。因此,任何内部更改都将丢失。
对于任何其他类型,Kotlin 会复制传递给函数的参数的引用。因此,参数的任何属性/字段更改也会更改调用者参数。
没有办法改变这种行为。
在尝试了许多方法来克服无法通过引用传递标量的问题后,就像 Kotlin、Java 和其他一些语言中发生的那样;我目前的策略是对任何标量类型使用普通和通用的包装,正如上面的评论所暗示的那样。
最近,我在所有事情上都使用了这个技巧,包括在一个函数中,否则它会要求我返回多个值。另一种方法是在人工类或解构声明中加入返回:val (a, b, c) = function-call()
句法。但是,我讨厌人工类并且解构声明仅适用于局部变量,当某些需要在当前命令块之外可见时,这很烦人。
我的代码很简单:
data class p<T>( // It's a generic wrap class for scalar type T
var v:T
)
fun <T>swap(a:p<T>, b:p<T>){ // It's a generic swap for scalar types
var aux:p<T> = a.copy()
a.v = b.v
b.v =aux.v
}
fun main() {
var a:p<Int> = p<Int>(2) // 'a' is a kind of 'Int' variable
var b:p<Int> = p<Int>(3) // and so is 'b'
swap(a,b) // Exchange 'a' and 'b' values
println(a.v) // 3
println(b.v) // 2
}
唯一的缺点是不能使用真正的标量类型的语法糖。
我被迫添加
.v
对标量变量的任何使用。我只将它用于需要在某些函数中通过引用传递的变量,这并不常见。如果可能,我会尽量避免附带影响。
关于kotlin - 在 Kotlin 中通过引用传递整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51638871/