问题描述
我知道,例如,Long
和路径依赖类型 foo.Long
是不同的类型。
但有Scala中的一个的方式路径无关型的值分配给路径依赖一个?
trait Encoder[T] {
def encode(v: T): String
}
val longIdEncoder: Encoder[Long] = (v: Long) => s"${v.toString} !!!"
trait Foo {
type Id
val id: Id
}
trait Bar {
val foo: Foo
val idEncoder: Encoder[foo.Id]
}
object FooImpl extends Foo {
override type Id = Long
override val id: Long = 10
}
object BarImpl extends Bar {
override val foo: Foo = FooImpl
override val idEncoder: Encoder[foo.Id] = longIdEncoder // <-- Error
}
当然,我得到:
type mismatch;
found : App.Encoder[Long]
required: App.Encoder[App.BarImpl.foo.Id]
override val idEncoder: Encoder[foo.Id] = longIdEncoder
我怎样才能克服这个问题?
解决方法
编译器只知道 foo
有一个类型 Foo
但它不知道是哪一个。所以你需要通过给 foo
一个更严格的类型来告诉它哪一个:
object BarImpl extends Bar {
override val foo: FooImpl.type = FooImpl
override val idEncoder: Encoder[foo.Id] = longIdEncoder
}
或者只是不为 foo 指定类型:
override val foo = FooImpl
编译器将为 foo
推断出更严格的类型,然后从更具体的 foo 实例中推断出 idEncoder
作为正确类型。
另一种方法是使用 asInstanceOf
强制类型:
override val idEncoder: Encoder[foo.Id] = longIdEncoder.asInstanceOf[Encoder[foo.Id]]
但这应该避免。