2011-11-24 32 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