Scala 使用shapess.Generic时,如何避免错误';除非通过名称';声明参数,否则无法向超级构造函数传递自引用;?
在现成的scala 2.12和shapeless 2.3.2下,以下简单程序无法编译:Scala 使用shapess.Generic时,如何避免错误';除非通过名称';声明参数,否则无法向超级构造函数传递自引用;?,scala,implicit,shapeless,Scala,Implicit,Shapeless,在现成的scala 2.12和shapeless 2.3.2下,以下简单程序无法编译: import shapeless.Generic object InferGeneric { class WithGeneric[T](implicit ev: Generic[T]) case class Impl() {} object Impl extends WithGeneric[Impl] } 编译器抛出以下错误: /.../InferGeneric.scala:11: s
import shapeless.Generic
object InferGeneric {
class WithGeneric[T](implicit ev: Generic[T])
case class Impl() {}
object Impl extends WithGeneric[Impl]
}
编译器抛出以下错误:
/.../InferGeneric.scala:11: super constructor cannot be passed a self reference unless parameter is declared by-name
object Impl extends WithGeneric[Impl]
有趣的是,当objectimpl
被重命名时,它可以毫无问题地编译。似乎泛型推理中使用的宏在与伴随对象组合时会导致某些循环解析。如何避免这种情况
非常感谢你的意见 问题在于宏生成的代码,但它不是真正特定于宏的。您可以使用显式定义的实例重现问题:
import shapeless._
class WithGeneric[T](implicit ev: Generic[T])
case class Impl()
object Impl extends WithGeneric[Impl]()(
new Generic[Impl] {
type Repr = HNil
def to(p: Impl): Repr = HNil
def from(p: Repr): Impl = Impl()
}
)
或者,如果要确保不涉及宏:
trait Generic[A] { def mk: A }
class WithGeneric[T](ev: Generic[T])
case class Impl()
object Impl extends WithGeneric[Impl](
new Generic[Impl] { def mk: Impl = Impl() }
)
通常,在实例化Impl
伴生对象时,无法在构造函数调用中传递调用Impl.apply
的代码
如果不了解更多关于如何使用和generic
的信息,就很难提出解决方案。在这种简单的情况下,您可以显式定义Generic[Impl]
,并且只使用new Impl
构造函数(而不是Impl.apply
)。如果您希望能够提供附带的对象便利方法,这些方法的定义可以抽象为case类,那么您可以执行以下操作:
import shapeless._
abstract class WithGeneric[T] {
def ev: Generic[T]
}
case class Impl()
object Impl extends WithGeneric[Impl] {
def ev: Generic[Impl] = Generic[Impl]
}
这只是一个小样板,但在不了解更多用例的情况下,我猜这可能是您最好的选择。非常感谢!希望下一版本的编译器能够支持这种语法。