gpt4 book ai didi

java - 复制同名属性的简单代码?

转载 作者:行者123 更新时间:2023-11-30 06:45:23 25 4
gpt4 key购买 nike

我有一个的问题在我脑海中盘旋了很长时间。当我在 Spring 中编写代码时,有很多用于 DTO、域对象的脏代码和无用代码。语言层面,Java无望,Kotlin看到一丝曙光。这是我的问题:

方式一我们通常会写如下代码(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
}

第一优先要求

  1. 只提供一次属性名称列表
  2. property name 是作为普通代码提供的,以便我们可以获得 IDE 自动完成功能。

第二优先级要求

  1. 它更愿意避免样式 3 的运行时成本。(例如,“反射”可能是一种可能的实现,但它确实会引入成本。)
  2. 更喜欢直接生成类似style1/style2的代码。

不关心

  1. Style 3 的最终语法。

我是 Kotlin 语言的新手。是否可以使用 Kotlin 来定义诸如“样式 3”之类的东西?

最佳答案

编写一个 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=)

关于java - 复制同名属性的简单代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49042656/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com