5

也许我误解了类的copy功能是如何data工作的,或者可能存在错误,但以下是该copy功能未按预期工作的示例:

科特林:

data class A {
    public var x: String? = null
    public var y: String? = null
    public var z: B = B.ONE
}

enum class B {
    ONE
    TWO
    THREE
}

爪哇

A a1 = new A()
a1.setX("Hello")
a1.setY("World")
a1.setZ(B.TWO)

A a2 = a1.copy()
// a2.x is null
// a2.y is null
// a2.z is B.ONE

似乎这copy只是创建一个新实例A而不是复制这些值。如果我将变量放在构造函数中,则会分配值,但这与构造一个新实例没有什么不同。

4

4 回答 4

8

好的,我在文档中错过了这句话:

如果这些函数中的任何一个在类主体中显式定义或从基类型继承,则不会生成它。

事实上,这copy并不比 Java 互操作的构造函数更好。

于 2015-02-20T02:40:08.807 回答
2

要绕过 Kotlin 的 copy() 的限制,您可以做的是在数据类中创建自己的复制函数。下面的例子:

data class User(val name : String, val property: String) {

    fun copy() : User {
      //uses the fields name and property defined in the constructor
      return User(name,property)
    }

    //or if you need a copy with a changed field
    fun copy(changedProperty : String) : User {
      return User(name, changedProperty)
    }

}
于 2017-10-30T15:49:47.837 回答
0

对于与 java 的互操作,您可以制作使用 kotlin 生成的 .copy 的函数

@Entity
data class User(@PrimaryKey var id: Int = 0,
            var firstName: String? = null,
            var lastName: String? = null,
            var phone: String? = null,
            var email: String? = null,
            var phoneCode: String? = null,
            var tokenId: String? = null,
            var provider: SocialProvider? = null) : Serializable {


var countryCodeIso: String? = null
    set(countryCodeIso) {
        if (countryCodeIso != null) {
            field = countryCodeIso.toLowerCase()
        }
    }

fun javaCopy(): User {
    val user = copy()
    user.countryCodeIso = countryCodeIso
    return user
}}
于 2018-02-16T09:54:20.423 回答
0

这个问题在搜索中的排名很高,对于那些刚接触 kotlin 的人来说可能会感到困惑,因为问题的示例代码不是典型的 kotlin 代码或复制功能的使用。我在下面添加了一些示例代码,以帮助阐明发生了什么,并展示了数据类的典型用法。
简而言之,copy从 kotlin 类调用该函数时最有用。我同意从 java 代码调用时它的行为并不明显。

//
// A.kt
//

// this is an idiomatic kotlin data class. note the parens around the properties, not braces.
data class A(
    val x: String? = null,
    val y: String? = null,
    val z: B = B.ONE
) {
    // this javaCopy function is completely unnecessary when being called from kotlin; it's only here to show a fairly simple way to make kotlin-java interop a little easier (like what Nokuap showed).
    fun javaCopy(): A {
        return this.copy()
    }
}

enum class B {
    ONE,
    TWO,
    THREE
}

fun main() {
    val a1 = A("Hello", "World", B.TWO)

    // here's what copy usage looks like for idiomatic kotlin code.
    val a2 = a1.copy()
    assert(a2.x == "Hello")
    assert(a2.y == "World")
    assert(a2.z == B.TWO)

    // more typical is to `copy` the object and modify one or more properties during the copy. e.g.:
    val a3 = a1.copy(y = "Friend")
    assert(a2.x == "Hello")
    assert(a3.y == "Friend")
}
public class App {

    public static void main(String[] args) {
        A a1 = new A("Hello", "World", B.TWO);

        // the kotlin copy function is primarily meant for kotlin <-> kotlin interop
        // copy works when called from java, but it requires all the args.
        // calling the `javaCopy` function gives the expected behavior.
        A a2 = a1.javaCopy();
        assert a2.getX().equals("Hello");
        assert a2.getY().equals("World");
        assert a2.getZ().equals(B.TWO);
    }
}

数据类的官方文档,包括copy函数:
https ://kotlinlang.org/docs/reference/data-classes.html

于 2020-02-25T01:59:42.053 回答