Kotlin 数据类复制方法不深度复制所有成员 [英] Kotlin data class copy method not deep copying all members

查看:56
本文介绍了Kotlin 数据类复制方法不深度复制所有成员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人能解释一下 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆