我有一个旧的问题长期存在于我的脑海中。当我在Spring中编写代码时,DTO,域对象有很多脏无用的代码。对于语言水平,我在Java中无望,并在Kotlin中看到了一些亮点。这是我的问题:
样式1 我们通常编写以下代码(Java,C ++,C#,...)
// annot: AdminPresentation
val override = FieldMetadataOverride()
override.broadleafEnumeration = annot.broadleafEnumeration
override.hideEnumerationIfEmpty = annot.hideEnumerationIfEmpty
override.fieldComponentRenderer = annot.fieldComponentRenderer
Sytle 2 在Kotlin中使用T.apply()
可以简化以前的代码
override.apply {
broadleafEnumeration = annot.broadleafEnumeration
hideEnumerationIfEmpty = annot.hideEnumerationIfEmpty
fieldComponentRenderer = annot.fieldComponentRenderer
}
Sytle 3 这样的代码甚至可以简化为这样的代码吗?
override.copySameNamePropertiesFrom (annot) { // provide property list here
broadleafEnumeration
hideEnumerationIfEmpty
fieldComponentRenderer
}
第一优先级要求
property name
个列表property name
作为普通代码提供,以便我们可以获得IDE自动完成功能。第二优先级要求
不关心
我是Kotlin语言的新手。是否可以使用Kotlin来定义类似于' Style 3' ?
答案 0 :(得分:4)
编写一个5行帮助程序来执行此操作应该非常简单,甚至支持复制每个匹配的属性或只选择属性。
虽然如果你正在编写Kotlin代码并大量使用数据类和val
(不可变属性),它可能没用。看看:
fun <T : Any, R : Any> T.copyPropsFrom(fromObject: R, vararg props: KProperty<*>) {
// only consider mutable properties
val mutableProps = this::class.memberProperties.filterIsInstance<KMutableProperty<*>>()
// if source list is provided use that otherwise use all available properties
val sourceProps = if (props.isEmpty()) fromObject::class.memberProperties else props.toList()
// copy all matching
mutableProps.forEach { targetProp ->
sourceProps.find {
// make sure properties have same name and compatible types
it.name == targetProp.name && targetProp.returnType.isSupertypeOf(it.returnType)
}?.let { matchingProp ->
targetProp.setter.call(this, matchingProp.getter.call(fromObject))
}
}
}
这种方法使用反射,但它使用非常轻量级的Kotlin反射。我没有计时,但它应该以与手动复制属性几乎相同的速度运行。
现在给出2个课程:
data class DataOne(val propA: String, val propB: String)
data class DataTwo(var propA: String = "", var propB: String = "")
您可以执行以下操作:
var data2 = DataTwo()
var data1 = DataOne("a", "b")
println("Before")
println(data1)
println(data2)
// this copies all matching properties
data2.copyPropsFrom(data1)
println("After")
println(data1)
println(data2)
data2 = DataTwo()
data1 = DataOne("a", "b")
println("Before")
println(data1)
println(data2)
// this copies only matching properties from the provided list
// with complete refactoring and completion support
data2.copyPropsFrom(data1, DataOne::propA)
println("After")
println(data1)
println(data2)
输出将是:
Before
DataOne(propA=a, propB=b)
DataTwo(propA=, propB=)
After
DataOne(propA=a, propB=b)
DataTwo(propA=a, propB=b)
Before
DataOne(propA=a, propB=b)
DataTwo(propA=, propB=)
After
DataOne(propA=a, propB=b)
DataTwo(propA=a, propB=)