如何在通用案例类上进行.copy而不直接扩展它们?

问题描述 投票:0回答:1

如何使用案例类

.copy
方法返回通用案例类的副本?

我正在努力实现以下目标:

def modifyNumber[T <: { def number: Int }](objectWithNumber: T, numberToReplace: Int): T = {
  objectWithNumber.copy(number = numberToReplace)
}

但我收到错误:

值副本不是类型参数 T 的成员

objectWithNumber.copy(number = numberToReplace)

这些案例类来自自动化 ORM 流程,因此我无法直接扩展它们。有办法解决吗?

以下是一些案例类别的示例:

case class One(someText: String, number: Int)
case class Two(otherStuff: List[Long], number: Int)

我能够创建通用函数,我可以像这样传递这两个案例类中的任何一个:

def addNumber[T <: { def number: Int }](objectWithNumber: T, numberToAdd: Int): Int = {
  objectWithNumber.number + numberToAdd
}

我也尝试过:

def modifyNumber[T <: Product with Serializable { def number: Int }](objectWithNumber: T, numberToReplace: Int): T = {
  objectWithNumber.copy(number = numberToReplace)
}

但是我得到了同样的错误。

如何实现

modifyNumber
以便它可以返回泛型的副本?这在 Scala 2.13.10(我使用的版本)上可能吗?

scala generics
1个回答
0
投票
  • 您有多个无法修改的类(
    One
    Two
    ,来自您的 ORM)
  • 您想要编写适用于所有这些类的多态代码

那么,为什么不直接使用临时多态性呢?

  • 您可以使用有点标准的
    Lens[A, Int]
    (例如来自Monocle),那么您的
    modifyNumber
    将成为
    Lens
    es
    set
    方法的包装:
    def modifyNumber[T](t: T, newNumber: Int)(using lens: Lens[T, Int]) =
      lens.set(newNumber)(t)
    
  • 如果您不想使用 Monocle,只需创建类似您自己的东西即可
    Lens
    trait CanCopyNumber[T]:
      def copy(t: T, n: Int): T
    
    ...
    
    def modifyNumber[T](t: T, newNumber: Int)(using c: CanCopyNumber[T]): T =
      c.copy(t, newNumber)
    
© www.soinside.com 2019 - 2024. All rights reserved.