2011-11-24 33 views
2

您好我读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 

什么是我的错?任何人都可以帮助我?

UPDATE

我的想法是这样的: 找到的是在性状不一无所知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(...) 
+0

我正在使用Scala 2.8.1 –

回答

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

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

也许你应该考虑定义一个DBObject2Business并且隐含地定义一个DBObject => Business函数,或者改变你的设计以在具体类中定义C