gpt4 book ai didi

具有动态命名参数的 Scala 案例类副本

转载 作者:行者123 更新时间:2023-12-02 00:07:34 29 4
gpt4 key购买 nike

对于具有多个参数(21!!)的 Scala 案例类

例如案例类 Car(类型:String,品牌:String,门:Int ....)其中类型 = 吉普车,品牌 = 丰田,门 = 4 ....等

还有一个复制方法允许使用命名参数覆盖:Car.copy(brand = Kia)哪里会变成 type = jeep, brand = Kia, door = 2...etc

我的问题是,无论如何我都可以动态提供命名参数吗?

def copyCar(key: String, name: String) = {
Car.copy("key" = "name") // this is something I make up and want to see if would work
}

scala 反射库可以提供帮助吗?

我使用复制方法的原因是,当我创建一个只更改了 1 或 2 个参数的案例类时,我不想每次都重复 21 个参数分配。

非常感谢!

最佳答案

FWIW,我刚刚实现了一个 Java 反射版本:CaseClassCopy.scala .我尝试了 TypeTag version但它并没有那么有用; TypeTag 对此目的限制太多。

  def copy(o: AnyRef, vals: (String, Any)*) = {
val copier = new Copier(o.getClass)
copier(o, vals: _*)
}

/**
* Utility class for providing copying of a designated case class with minimal overhead.
*/
class Copier(cls: Class[_]) {
private val ctor = cls.getConstructors.apply(0)
private val getters = cls.getDeclaredFields
.filter {
f =>
val m = f.getModifiers
Modifier.isPrivate(m) && Modifier.isFinal(m) && !Modifier.isStatic(m)
}
.take(ctor.getParameterTypes.size)
.map(f => cls.getMethod(f.getName))

/**
* A reflective, non-generic version of case class copying.
*/
def apply[T](o: T, vals: (String, Any)*): T = {
val byIx = vals.map {
case (name, value) =>
val ix = getters.indexWhere(_.getName == name)
if (ix < 0) throw new IllegalArgumentException("Unknown field: " + name)
(ix, value.asInstanceOf[Object])
}.toMap

val args = (0 until getters.size).map {
i =>
byIx.get(i)
.getOrElse(getters(i).invoke(o))
}
ctor.newInstance(args: _*).asInstanceOf[T]
}
}

关于具有动态命名参数的 Scala 案例类副本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17312254/

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