Scala隐式参数有问题

时间:2014-03-06 12:38:52

标签: scala implicit-conversion implicit

我有以下代码,它将成为隐式对象的基础:

trait Foo[-T] {
  def hello(obj: T)
}

trait Model extends Serializable {
  def bar()(implicit foo: Foo[Model]) = { foo.hello(this) }
}

class SerializableFoo[T <: Serializable] extends Foo[T] {
  def hello(obj: T) { println("hello from SerializableFoo") }
}

class FOSModelFoo[T <: Model] extends Foo[T] {
  def hello(obj: T) { println("hello from FOSModelFoo") }
}

object Foo {
  implicit object DefaultFoo extends SerializableFoo[Model]
}

class FOSModel extends Model {
   implicit object InnerFoo extends FOSModelFoo
}

当我在FOSModel实例上调用bar()时,我期待使用FOSModelFoo,但它正在调用SerializableFoo。

我错过了什么?

1 个答案:

答案 0 :(得分:2)

问题1:implicit object InnerFoo在(或导入)中定义的范围内可用作隐式。如果您InnerFoo随处可用,则应在object Fooobject FOSModel中定义:

object Foo {
  implicit object DefaultFoo extends SerializableFoo[Model]
  implicit object InnerFoo extends FOSModelFoo[FOSModel]
}

问题2:Implicits依赖于静态类型,而不是运行时类型,因此如果编译器只知道它是Model,那么使用哪个实例并不重要。 E.g。

val fosModel: Model = new FOSModel

问题3:由于您要求Foo[Model]而不是Foo[FOSModel]DefaultFoo是唯一适合的人。

我无法确切地说出你想要什么,但这似乎是一个不完整的“奇怪的反复出现的模板模式”。它可能类似于

trait Model[T <: Model[T]] extends Serializable {
  def bar()(implicit foo: Foo[T]) = { foo.hello(this) }
}

class FOSModel extends Model[FOSModel]

object FOSModel {
  implicit object InnerFoo extends FOSModelFoo
}
...