Kotlin 数据类复制方法不深度复制所有成员 [英] Kotlin data class copy method not deep copying all members
问题描述
有人能解释一下 Kotlin 数据类的 copy
方法究竟是如何工作的吗?似乎对于某些成员来说,实际上并未创建(深层)副本,并且引用仍然是原始的.
有趣的测试(){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酒吧.x = 2foo.list.add(4)println("foo : $foo")println("fooCopy: $fooCopy")println("barCopy: $barCopy")}数据类 Foo(var a: Int,瓦尔酒吧:酒吧,val 列表:MutableList= mutableListOf())数据类 Bar(var x: Int = 0)
<块引用>
输出:
foo : foo(a=5, bar=Bar(x=0), list=[1, 2, 3])
foo : 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])
条形复制:条形(x=0)
为什么是 barCopy.x=0
(预期),但 fooCopy.bar.x=2
(我认为应该是 0).由于 Bar
也是一个数据类,我希望 foo.bar
在执行 foo.copy()
时也是一个副本.
要深度复制所有成员,我可以这样做:
val fooCopy = foo.copy(bar = foo.bar.copy(), list = foo.list.toMutableList())
<块引用>
fooCopy: Foo(a=5, bar=Bar(x=0), list=[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 = this.list) = Foo(a, bar, list)fun copy(x: Int = this.x) = Bar(x)
Could someone explain how exactly the copy
method for Kotlin data classes work? It seems like for some members, a (deep) copy is not actually created and the references are still to the original.
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)
Output:
foo : Foo(a=5, bar=Bar(x=0), list=[1, 2, 3])
foo : 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: Bar(x=0)
Why is barCopy.x=0
(expected), but fooCopy.bar.x=2
(I would think it would be 0). Since Bar
is also a data class, I would expect foo.bar
to also be a copy when foo.copy()
is executed.
To deep copy all members, I can do something like this:
val fooCopy = foo.copy(bar = foo.bar.copy(), list = foo.list.toMutableList())
fooCopy: Foo(a=5, bar=Bar(x=0), list=[1, 2, 3])
But am I missing something or is there a better way to do this without needing to specify that these members need to force a deep copy?
The copy
method of Kotlin is not supposed to be a deep copy at all. As explained in the reference doc (https://kotlinlang.org/docs/reference/data-classes.html), for a class such as:
data class User(val name: String = "", val age: Int = 0)
the copy
implementation would be:
fun copy(name: String = this.name, age: Int = this.age) = User(name, age)
So as you can see, it's a shallow copy. The implementations of copy
in your specific cases would be:
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)
这篇关于Kotlin 数据类复制方法不深度复制所有成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!