Kotlin数据类复制方法未深度复制所有成员 [英] Kotlin data class copy method not deep copying all members
问题描述
有人可以解释一下Kotlin数据类的copy
方法是如何工作的吗?对于某些成员来说,似乎并没有实际创建(深层)副本,并且引用仍然是原始副本.
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)
输出:
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)
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)
为什么是barCopy.x=0
(预期),但为什么是fooCopy.bar.x=2
(我认为它将是0).由于Bar
也是数据类,所以我希望foo.bar
在执行foo.copy()
时也成为副本.
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])
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?
推荐答案
Kotlin的copy
方法根本不应该是深层复制.如参考文档( https://kotlinlang.org/docs/reference/data- classes.html ),例如:
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)
copy
实现为:
fun copy(name: String = this.name, age: Int = this.age) = User(name, age)
如您所见,它是一个浅表副本.在您的特定情况下,copy
的实现为:
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屋!