Kotlin数据类复制方法不深拷贝所有成员
问题描述:
有人可以解释Kotlin数据类的copy
方法的工作原理吗?对于某些成员来说,似乎(实际)复制实际上并未创建,并且引用仍然是原始的。Kotlin数据类复制方法不深拷贝所有成员
fun test() {
val bar = Bar(0)
val foo = Foo(5, bar, mutableListOf(1, 2, 3))
println("foo : $foo")
val barCopy = bar.copy()
val fooCopy = foo.copy()
foo.a = 10
bar.x = 2
foo.list.add(4)
println("foo : $foo")
println("fooCopy: $fooCopy")
println("barCopy: $barCopy")
}
data class Foo(var a: Int,
val bar: Bar,
val list: MutableList<Int> = mutableListOf())
data class Bar(var x: Int = 0)
输出:
FOO:美孚(α= 5,条=栏(X = 0),则列表= [1,2,3])
FOO:美孚(A = 10, bar = Bar(x = 2),list = [1,2,3,4])
fooCopy:Foo(a = 5,bar = Bar(x = 2),list = [1,2,3,4 ])
barCopy:酒吧(X = 0)
为什么barCopy.x=0
(预期),但fooCopy.bar.x=2
(我认为这将是0)。由于Bar
也是一个数据类,所以当foo.copy()
执行时,我预计foo.bar
也是一个副本。
要深拷贝所有成员,我可以做这样的事情:
val fooCopy = foo.copy(bar = foo.bar.copy(), list = foo.list.toMutableList())
fooCopy:美孚(α= 5,条=栏(X = 0),则列表= [1,2, 3])
但是我错过了什么或有没有更好的方法来做到这一点,而无需指定这些成员需要强制深度复制?
答
Kotlin的copy
方法根本不应该是深层复制。正如参考文档(https://kotlinlang.org/docs/reference/data-classes.html)解释说,一类如:
data class User(val name: String = "", val age: Int = 0)
的copy
实现是:
fun copy(name: String = this.name, age: Int = this.age) = User(name, age)
因此,大家可以看到,这是一个浅拷贝。的copy
在特定情况下的实现将是:
fun copy(a: Int = this.a, bar: Bar = this.bar, list: MutableList<Int> = this.list) = Foo(a, bar, list)
fun copy(x: Int = this.x) = Bar(x)
答
正如@Ekeko说,对于数据类实现的默认copy()
功能是浅拷贝,看起来像这样:
fun copy(a: Int = this.a, bar: Bar = this.bar, list: MutableList<Int> = this.list)
要执行深拷贝,则必须覆盖copy()
函数。
fun copy(a: Int = this.a, bar: Bar = this.bar.copy(), list: MutableList<Int> = this.list.toList()) = Foo(a, bar, list)