我想知道为什么以下情况不起作用。假设我有两种类型:
trait Def[T]
trait Ref[T]
case class Module()
我想将Def
转换为Ref
,因此我宣布以下方法:
object Ref {
implicit def fromDef[A](defin: Def[A])(implicit rc: RefConverter[A]): Ref[rc.ResType] = new Ref[rc.ResType] {}
}
但是以防万一:
val moduleDef: Def[Module] = ???
val moduleRef: Ref[Module] = moduleDef
Scala编译器无法找到正确的转换方式(即fromDef
函数),但如果我们明确告诉它使用此转换,即Ref.fromDef(moduleDef)
,scalac会找到正确的{{ 1}}实例。另一个需要考虑的重要事项是,如果我将结果类型更改为RefConverter
,它也会解析转换链。那么编译器无法解析具有依赖结果类型的链?
答案 0 :(得分:2)
您必须将类型参数和类型成员绑定在一起。
您可以在其他答案中提供别名;请注意,它不适用于特征中绑定的类型,请参阅代码注释。
但是你可以提供另一种有界的类型参数:
trait Ref[T]
trait Def[T]
case class Module()
object Ref {
//implicit def fromDef[A](defin: Def[A])(implicit rr: RefResolver[A]): Ref[rr.RefType] = new Ref[rr.RefType] {}
//implicit def fromDef[A](defin: Def[A])(implicit rr: RefResolver[A]): Ref[A] = new Ref[A] {} // OP notes that this works
implicit def fromDef[A, B <: A](defin: Def[A])(implicit rr: RefResolver[B]): Ref[B] = new Ref[B] {}
// or
implicit def fromDef[A](defin: Def[A])(implicit rr: RefResolver[A]): Ref[A] { type RefType <: A } = new Ref[A] { type RefType = A }
}
trait RefResolver[A] {
type RefType
//type RefType <: A // not good enough
}
object RefResolver {
implicit val moduleRes: RefResolver[Module] { type RefType = Module } =
new RefResolver[Module] {
type RefType = Module
}
}
object Test extends App {
val moduleDef: Def[Module] = new Def[Module] {}
val moduleRef: Ref[Module] = moduleDef
}
答案 1 :(得分:0)
以下编译:
trait Def[T]
trait Ref[T]
case class Module()
trait RefConverter[T]{
type ResType = T
type RefType = T
}
object Ref {
implicit def fromDef[A](defin: Def[A])(implicit rc: RefConverter[A]): Ref[rc.ResType] = new Ref[rc.RefType] {}
}
implicit val rc = new RefConverter[Module]{}
val d = new Def[Module]{}
val r = d:Ref[Module]
答案 2 :(得分:0)
这会编译并打印类型:
object Test extends App {
implicit val rc = new RefConverter[Module] {}
object Ref {
implicit def fromDef[A](defin: Def[A])(implicit rc: RefConverter[A]): Ref[rc.ResType] = new Ref[rc.ResType] {}
}
val moduleDef: Def[Module] = new Def[Module]() {}
val moduleRef: Ref[Module] = moduleDef
println(moduleDef.getClass.getName)
println(moduleRef.getClass.getName)
trait RefConverter[T] {
type ResType = T
}
trait Def[T]
trait Ref[T]
case class Module()
}
我认为你的Refconverter要么不在范围内,要么你的IDE误导了你的错误。