如何隐式使用函数?

时间:2011-11-24 12:56:32

标签: scala implicit

您好我读了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是在一个特性中声明的,对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(...)

2 个答案:

答案 0 :(得分:7)

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)

答案 1 :(得分:1)

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

也许您应该考虑定义DBObject2Business,然后隐式定义DBObject => Business函数,或更改您的设计以在具体类中定义C