You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将父对象解构后传入扩展子类的构造函数(Scala样例类场景)

Scala 复用 case class 属性构造新实例的实现方案

以下是几种常用实现方式,按复杂度从低到高排列:

方案1:直接手动取值(最通用,无额外依赖)

小场景下直接取已有实例的属性传入即可,语法最直观,没有额外性能开销:

case class Cat(name: String) 
case class PetPersian(name: String, price: Number) 

val c1 = Cat(name = "Meowth")
val c2 = PetPersian(
  name = c1.name,
  price = 10000
)

方案2:用tupled方法结合Product特性(适合属性较多的场景)

case class 默认实现Product特质,可通过tupled方法将元组转换为构造函数入参:

// 先把Cat实例转成元组,拼接price参数后传入tupled方法
val c2 = PetPersian.tupled( (c1.name, 10000) )

// 如果属性很多不想逐个写,可动态拼接元组(Scala 2.13+ 原生支持)
val c2 = PetPersian.tupled(
  Tuple.fromProduct(c1) :+ 10000
)

方案3:隐式扩展方法(高频转换场景调用更简洁)

如果经常需要做Cat到PetPersian的转换,可以定义扩展方法简化调用逻辑:

// 定义扩展方法
implicit class CatOps(cat: Cat) {
  def toPetPersian(price: Number): PetPersian = PetPersian(cat.name, price)
}

// 调用代码非常简洁
val c2 = c1.toPetPersian(10000)

方案4:Shapeless自动映射(重叠属性多的复杂场景)

如果两个case class重叠属性非常多,不想手动写属性映射,可以用Shapeless第三方库做自动字段匹配,不需要逐一声明属性对应关系:

import shapeless._
import syntax.singleton._

case class Cat(name: String)
case class PetPersian(name: String, price: Number)

val c1 = Cat("Meowth")
// 自动提取匹配的属性,仅额外传入新增的price参数
val c2 = LabelledGeneric[PetPersian].from(
  LabelledGeneric[Cat].to(c1) :+ ('price ->> 10000)
)

内容的提问来源于stack exchange,提问作者user2167582

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.11 08:48:02