2017-11-17 103 views
3

누군가 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는 : 푸 (a = 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.bar도 사본이 될 것으로 예상됩니다.

모든 회원 깊은 복사하려면, 나는이 같은 작업을 수행 할 수 있습니다

val fooCopy = foo.copy(bar = foo.bar.copy(), list = foo.list.toMutableList()) 

fooCopy : 푸 (A = 5, 바 = 바 (X = 0), 목록 = [1, 2, 3])

그러나 나는 뭔가를 놓치고 있습니까? 아니면이 구성원이 전체 복사본을 강제로 작성해야한다고 지정하지 않아도이를 수행 할 수있는 더 좋은 방법이 있습니까?

답변

8

copy Kotlin의 방법은 깊은 복사가 아닐 수 있습니다.

data class User(val name: String = "", val age: Int = 0) 

copy 구현은 다음과 같습니다 : 같은 클래스, 참조 문서 (https://kotlinlang.org/docs/reference/data-classes.html)에서 설명하고있는 바와 같이

fun copy(name: String = this.name, age: Int = this.age) = User(name, age) 

당신이 볼 수 그래서, 그것은 shallow 복사합니다. 특정 경우에 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) 
1

@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)