如何在Kotlin Data Class中使用依赖其他构造参数的默认值?
解决Data Class构造参数依赖非属性参数的问题
方案一:使用次级构造器
data class要求主构造器的所有参数必须是带val/var的属性,所以可以把需要保留的属性放在主构造器,用次级构造器处理非属性的clock参数,同时初始化timeCreated:
import java.time.Clock import java.time.Instant data class MyObject( val name: String, val timeCreated: Instant ) { // 次级构造器,接收clock参数并生成timeCreated的默认值 constructor(name: String, clock: Clock = Clock.systemUTC()) : this(name, clock.instant()) } fun main() { // 正常使用,无需传clock val a = MyObject(name = "Fred") println(a.timeCreated) // 测试时传入自定义clock val testClock = Clock.fixed(Instant.parse("2024-01-01T00:00:00Z"), Clock.systemUTC().zone) val b = MyObject(name = "Test", clock = testClock) println(b.timeCreated) // 输出指定时间 }
这样clock不会成为类的属性,同时MyObject作为data class,自动生成的toString、copy、equals等方法都能正常使用。
方案二:使用工厂函数
如果不想写次级构造器,可以通过顶层函数或伴生对象的工厂函数来处理测试场景,主构造器直接设置timeCreated的默认值:
import java.time.Clock import java.time.Instant data class MyObject( val name: String, val timeCreated: Instant = Clock.systemUTC().instant() ) // 测试专用的工厂函数 fun MyObject(name: String, clock: Clock): MyObject { return MyObject(name, clock.instant()) } fun main() { val a = MyObject(name = "Fred") println(a.timeCreated) val testClock = Clock.fixed(Instant.parse("2024-01-01T00:00:00Z"), Clock.systemUTC().zone) val b = MyObject(name = "Test", clock = testClock) println(b.timeCreated) }
这种方式更简洁,主构造器完全符合data class的要求,测试时通过工厂函数传入自定义时钟即可。
内容的提问来源于stack exchange,提问作者k314159
相关产品推荐
相关产品推荐

