You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin中copy方法参数说明及接口适配data class copy的参数定义

Kotlin Data Class的copy方法参数

Kotlin编译器会自动为data class生成copy方法,它的参数对应data class的所有属性,且每个参数都带有默认值——默认值就是原对象该属性的当前值。

举个例子,若Foobar的定义为:

data class Foobar(val id: Int, val name: String, val active: Boolean = true) : Fizzbuzz

编译器生成的copy方法签名会是:

fun copy(id: Int = this.id, name: String = this.name, active: Boolean = this.active): Foobar

调用时只需传入需要修改的属性,比如foobar.copy(name = "newName"),未指定的属性会沿用原对象的值。

Fizzbuzz接口的clone方法参数设计

因为接口是抽象的,需兼顾扩展性,这里提供两种实用方案:

方案1:与特定实现类的copy参数强绑定(仅适用于接口仅服务Foobar的场景)

如果Fizzbuzz接口只针对Foobar设计,可让clone方法的参数与Foobar的copy参数完全一致:

interface Fizzbuzz {
    fun clone(id: Int = this.id, name: String = this.name, active: Boolean = this.active): Fizzbuzz
}

data class Foobar(val id: Int, val name: String, val active: Boolean = true) : Fizzbuzz {
    override fun clone(id: Int = this.id, name: String = this.name, active: Boolean = this.active): Foobar {
        return this.copy(id = id, name = name, active = active)
    }
}

缺点是接口与具体实现强耦合,新增其他data class实现时需修改接口,扩展性差。

方案2:泛型+Lambda的通用方案(推荐)

通过泛型让接口与实现类绑定,用Lambda灵活修改属性,适配任意data class:

interface Fizzbuzz<T : Fizzbuzz<T>> {
    fun clone(block: T.() -> Unit): T
}

data class Foobar(val id: Int, val name: String, val active: Boolean = true) : Fizzbuzz<Foobar> {
    override fun clone(block: Foobar.() -> Unit): Foobar {
        return this.copy().apply(block)
    }
}

调用时可像这样修改属性:

val original = Foobar(1, "test")
val cloned = original.clone { 
    name = "newTest"
    active = false
}

这种方式既保留了类似copy的灵活修改能力,又让接口具备通用性,不同data class实现只需指定泛型类型即可。

内容的提问来源于stack exchange,提问作者Patrick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 02:10:57