【问题标题】:How to use implicitly with a function?如何隐式使用函数?
【发布时间】:2011-11-24 12:56:31
【问题描述】:

您好,我阅读了 Debasish 关于隐式函数的有趣帖子。我写了这段代码:

def find[C <: Business](id: String) = {
  collection.findOneByID(id).map(x=> implicitly[DBObject => C].apply(x))
}

但它无法使用此编译器消息进行编译:

could not find implicit value for parameter e: (com.mongodb.casbah.commons.Imports.DBObject) => C

我的错是什么?谁能帮帮我?

更新

我的想法是这样的: find 在 trait 中声明 对 DBObject 一无所知,我不想放这个依赖。

 trait BusinessRepository {
   def find[C <: Business](id: String): Option[C]
 }

class MongoBusinessRepository {

  val collection = ..

  def find[C <: Business](id: String): Option[C] = {
    collection.findOneByID(id).map(x=> implicitly[DBObject => C].apply(x))         
  }

  implicit def DBObject2Hotel(x: DBObject): Hotel = {
    // ... 
    // returning Hotel
  }
}

case class Hotel(...) extends Business(...)

【问题讨论】:

    标签: scala implicit


    【解决方案1】:

    implicitly 只是一种方便的方法来查找您知道已经存在的隐式值。因此,当作用域中没有这样的隐式值时,它无法编译。

    一个可能的用例是当您使用快捷语法作为上下文边界时:

    def find[C: Numeric](a: C, b: C): C = implicitly[Numeric[C]].plus(a, b)
    

    当然,在这个例子中,显式形式不那么冗长

    def find[C](a: C, b: C)(implicit n: Numeric[C]): C = n.plus(a, b)
    

    你会在this Stackoverflow thread找到更详尽的解释。


    我想你对你的方法的想法是

    def find[C <: Business](id: String)(implicit fun: DBObject => C) =
      collection.findOneByID(id).map(fun)
    

    【讨论】:

      【解决方案2】:

      我认为问题在于 Scala 编译器试图找到函数 DBObject =&gt; C 的隐式定义,而他唯一能找到的隐式定义是 DBObject =&gt; Hotel,这可能是一个解决方案,但并不严格.使用您的解决方案,编译器无法知道 C 应该是什么。

      也许您应该考虑定义 DBObject2Business 并隐式定义 DBObject =&gt; Business 函数,或者更改您的设计以在具体类中定义 C

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-12-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-23
        • 1970-01-01
        • 2012-05-04
        相关资源
        最近更新 更多