在Kotlin中,是否有一种惯用的方法让(二级)构造函数为主构造函数派生值?
我有一个简单的Kotlin课程:在Kotlin中,是否有一种惯用的方法让(二级)构造函数为主构造函数派生值?,kotlin,Kotlin,我有一个简单的Kotlin课程: data class ValveSpan(val begin:Duration, val end:Duration, val key:String):Comparable<ValveSpan> { ... } 基本上,次要构造函数的目的是获取输入,为主要构造函数计算一些值,然后用这些值调用主要构造函数。但似乎我必须在主构造函数中内联地完成它们。随着推导越来越复杂,也越来越复杂。我真的很想写一些东西,比如: constructor(doc:T
data class ValveSpan(val begin:Duration, val end:Duration, val key:String):Comparable<ValveSpan> {
...
}
基本上,次要构造函数的目的是获取输入,为主要构造函数计算一些值,然后用这些值调用主要构造函数。但似乎我必须在主构造函数中内联地完成它们。随着推导越来越复杂,也越来越复杂。我真的很想写一些东西,比如:
constructor(doc:TSON) {
var sanitizedBegin = doc["begin"].duration ?: 0.minutes
var sanitizedEnd = doc["end"].duration ?: 0.minutes
var sanitizedKey = doc["valves"].sequence?.firstOrNull()?.string ?: ""
primaryConstructor(sanitizedBegin, sanitizedEnd, sanitizedKey)
}
没有办法委托给主构造函数,而不必内联执行所有桥接计算吗?您可以使用伴随对象来实现此目的:
data class ValveSpan(val begin:Duration, val end:Duration, val key:String) {
companion object {
fun fromDoc(doc:TSON): ValveSpan {
var sanitizedBegin = doc["begin"].duration ?: 0.minutes
var sanitizedEnd = doc["end"].duration ?: 0.minutes
var sanitizedKey = doc["valves"].sequence?.firstOrNull()?.string ?: ""
return ValveSpan(sanitizedBegin, sanitizedEnd, sanitizedKey)
}
}
}
用法:
ValveSpan.fromDoc(doc)
您可以为此目的使用伴生对象:
data class ValveSpan(val begin:Duration, val end:Duration, val key:String) {
companion object {
fun fromDoc(doc:TSON): ValveSpan {
var sanitizedBegin = doc["begin"].duration ?: 0.minutes
var sanitizedEnd = doc["end"].duration ?: 0.minutes
var sanitizedKey = doc["valves"].sequence?.firstOrNull()?.string ?: ""
return ValveSpan(sanitizedBegin, sanitizedEnd, sanitizedKey)
}
}
}
用法:
ValveSpan.fromDoc(doc)
为了增加@ahmed ashraf gamal的功能,您还可以通过引入一个同伴对象来模拟从ValveSpan的客户端调用构造函数,该对象在同伴对象上定义一个调用操作符。例如:
data class ValveSpan(val begin:Duration, val end:Duration, val key:String) {
companion object {
operator fun invoke(doc:TSON): ValveSpan {
var sanitizedBegin = doc["begin"].duration ?: 0.minutes
var sanitizedEnd = doc["end"].duration ?: 0.minutes
var sanitizedKey = doc["valves"].sequence?.firstOrNull()?.string ?: ""
return ValveSpan(sanitizedBegin, sanitizedEnd, sanitizedKey)
}
}
}
这将允许您调用ValveSpan(doc)
为了增加@ahmed ashraf gamal的功能,您还可以通过引入一个同伴对象来模拟从ValveSpan的客户端调用构造函数,该同伴对象在同伴对象上定义一个调用操作符。例如:
data class ValveSpan(val begin:Duration, val end:Duration, val key:String) {
companion object {
operator fun invoke(doc:TSON): ValveSpan {
var sanitizedBegin = doc["begin"].duration ?: 0.minutes
var sanitizedEnd = doc["end"].duration ?: 0.minutes
var sanitizedKey = doc["valves"].sequence?.firstOrNull()?.string ?: ""
return ValveSpan(sanitizedBegin, sanitizedEnd, sanitizedKey)
}
}
}
这将允许您调用
ValveSpan(doc)
没有。Java也不支持这种给人希望的方式(至少上次我尝试过这样做)。:/我想成为一个更好的iOS/Android swift/kotlin polyglot。科特林很酷。但有时我只想拍我的头,直到它在键盘上血淋淋。使用companion对象将非常适合这个用例,它将像类的工厂一样工作,你可以有你想要的任何派生逻辑。那会是什么样子的@Ahmedashraffgamal?我必须在companion上使用静态风格的工厂方法,正当基本上fundoc(doc:TSON):ValveSpan{…}
代替constructor
关键字?然后,我会使用ValveSpan.doc(doc)
,而不是通过看起来像构造函数的东西来创建它们。不,Java实际上也不支持这一点(至少上次我尝试过)给人希望的方式。:/I正在努力成为一个更好的iOS/Android swift/kotlin polyglot。kotlin很酷。但有时我只是想拍我的头,直到它在键盘上血淋淋的。使用伴生对象将非常适合这个用例,它将像类的工厂一样工作,并且你可以拥有你想要的任何派生逻辑这看起来像@AhmedAshrafGamal吗?我必须在companion上有静态风格的工厂方法,对吗?基本上是fundoc(doc:TSON):ValveSpan{…}
来代替构造函数
关键字?然后不是通过看起来像构造函数的东西来创建它们(例如ValveSpan(doc))
,我会使用ValveSpan.doc(doc)
?不知道,尼斯:)不知道,尼斯:)