【问题标题】:Trouble with Scala implicit argumentsScala隐式参数的问题
【发布时间】:2014-03-06 21:28:54
【问题描述】:

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

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。

我错过了什么?

【问题讨论】:

    标签: scala implicit-conversion implicit


    【解决方案1】:

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

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

    问题 2:隐式依赖于静态类型,而不是运行时类型,所以如果编译器只知道它是 Model,那么使用什么实例并不重要。例如

    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
    }
    ...
    

    【讨论】:

    • 我按你说的试过了,还是一样。我要做的基本上是有一个默认的隐式 Foo (SerializableFoo) 与模型 (Model trait) 一起使用,并为模型的特定实例 (FOSModel) 提供特定的 Foo (FOSModelFoo) 实例。
    • 你考虑到问题2了吗? IE。如果 static 类型在这两种情况下都是 Model,那么你就无法得到你想要的。如果是,请使用更新的代码编辑问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-02
    • 2021-05-02
    相关资源
    最近更新 更多