在scala中,如果在家庭外部类型中声明了案例类,如何调用它的通用复制函数?

问题描述

这是路径依赖类型导致的scala问题:考虑到我有一个家庭类型:

trait Outer {
  
  case class Inner(v: Int) {

    val outer = Outer.this
  }
}

如果我想在 Outer#Inner.copy() 的实例未知时调用 Outer

def cp(src: Outer#Inner) = {
  src.copy()
}

我会遇到编译错误。因为 src.copy() 的类型签名附加到其外部实例。

绕过这一点的一种方法是手动提取外部实例:

def cp(src: Outer#Inner) = {
  val o = src.outer
  val _src = src.asInstanceOf[o.Inner]

  _src.copy()
}

这可以成功编译,但 asInstanceOf[] 显然是黑客制品,应该删除

在惯用的scala中,实现相同目标的最佳方法是什么,同时让scala编译器自动推断outer的存在,并生成正确的类型签名而无需盲目类型转换?

解决方法

您需要使用类型参数来约束 Outer#Inner 类型,而不是 Outer。试试

def cp[O <: Outer](src: O#Inner): O#Inner = src.copy()

这将允许您维护 O#Inner,它指的是一种特定类型,而不是 Outer#Inner

Scastie 中查看。