【发布时间】:2015-11-18 14:04:26
【问题描述】:
在下面的示例中,有没有办法避免隐式解析选择defaultInstance 而使用intInstance?代码后的更多背景:
// the following part is an external fixed API
trait TypeCls[A] {
def foo: String
}
object TypeCls {
def foo[A](implicit x: TypeCls[A]) = x.foo
implicit def defaultInstance[A]: TypeCls[A] = new TypeCls[A] {
def foo = "default"
}
implicit val intInstance: TypeCls[Int] = new TypeCls[Int] {
def foo = "integer"
}
}
trait FooM {
type A
def foo: String = implicitly[TypeCls[A]].foo
}
// end of external fixed API
class FooP[A:TypeCls] { // with type params, we can use context bound
def foo: String = implicitly[TypeCls[A]].foo
}
class MyFooP extends FooP[Int]
class MyFooM extends FooM { type A = Int }
object Main extends App {
println(s"With type parameter: ${(new MyFooP).foo}")
println(s"With type member: ${(new MyFooM).foo}")
}
实际输出:
With type parameter: integer
With type member: default
期望的输出:
With type parameter: integer
With type member: integer
我正在使用使用上述方案为类型类TypeCls 提供“默认”实例的第三方库。我认为上面的代码是一个演示我的问题的最小示例。
用户应该混合FooM 特征并实例化抽象类型成员A。问题是由于defaultInstance,(new MyFooM).foo 的调用不能解决专门的intInstance,而是提交给defaultInstance,这不是我想要的。
我添加了一个使用类型参数的替代版本,称为FooP(P = 参数,M = 成员),它避免通过使用类型参数上的上下文绑定来解析defaultInstance。
对于类型成员是否有等效的方法?
编辑:我的简化有一个错误,实际上foo 不是def 而是val,因此无法添加隐式参数。所以目前的答案都不适用。
trait FooM {
type A
val foo: String = implicitly[TypeCls[A]].foo
}
// end of external fixed API
class FooP[A:TypeCls] { // with type params, we can use context bound
val foo: String = implicitly[TypeCls[A]].foo
}
【问题讨论】:
标签: scala implicit type-members