2012-07-19 54 views
3

我在寫一個訪問數據庫的Scala應用程序。大多數情況下,會有可用的連接,但有時不會有。我想要做的就是像下面這樣:在斯卡拉,有沒有一種方法可以有兩種重載的方法,只有不同的隱式是否可用?

object User { 
    def authenticate(username: String, password: String) 
     (implicit conn: Connection): Option[User] = { 
    // use conn to grab user from db and check that password matches 
    // return Some(user) if so, None if not 
    } 
    def authenticate(username: String, password: String): Option[User] = { 
    implicit val conn = DB.getConnection() 
    authenticate(username, password) 
    } 
} 

我希望會發生的是,如果有Connection類型可用的隱含價值,編譯器會使用第一種方法。如果沒有,它會使用第二個。不幸的是,我發現編譯器並不那麼聰明,如果是這樣,我不會告訴它以正確的方式做什麼。

所以,我的基本問題是,有沒有辦法編寫一個方法,需要一個隱式參數,然後提供一個重載版本的相同方法,創建一個隱式參數類型的可接受值,如果沒有一個可用。

你可能會說:「你爲什麼想要做這樣的事情?如果你可以創建一個合適的適當類型的值,爲什麼不總是這樣做?」大多數情況都是如此,除非如果我有一個開放的數據庫連接,我寧願繼續使用它,而不是創建一個新的連接。但是,如果我沒有打開數據庫連接,我知道從哪裏得到一個。

我的意思是,簡單的答案是給這兩種方法不同的名稱,但我不應該,天哪,它 - 它。但也許我做...

謝謝! Todd

+0

什麼包裹中的一些連接負責調用'getConnection'並存儲的類?那麼你只需要一種方法將這個新類作爲隱含的。 – pedrofurla 2012-07-19 03:30:20

回答

9

您不需要重載的方法。只要給你的隱含參數的默認值,即

object User { 
    def authenticate(username:String, password:String)(implicit conn:Connection = null): Option[User] = { 
    val real_conn = Option(conn).getOrElse(DB.getConnection()) 
    // do the rest with the real_conn 
    } 
} 
+0

conn會爲空? – pedrofurla 2012-07-19 03:31:15

+1

爲什麼不隱含conn:Option [Connection]? – pedrofurla 2012-07-19 03:31:55

+0

如果你沒有在範圍內給出一個隱含的值,那麼conn將爲空,否則它將採用該值。當然,您可以使用Option [Connection],但需要您修改您的上下文代碼,這可能會有很多變化。 – xiefei 2012-07-19 03:32:21

0

的清潔解決方案,我能想到的是使用嵌套的方法和有人建議,對於implicits默認值。

class Testclass { 

    def myMethod(a:Int)(implicit b:Option[Int]=None):Int = { 

    def myMethodInternal(a:Int, b:Int):Int = { 
     // do something 
     a+b 
    } 
    val toUse = b.getOrElse(30) 
    myMethodInternal(a,toUse) 
    } 
} 

裏面你的方法,你定義一個myMethodInternal,它沒有任何implicits但只有清楚地表達參數。這種方法將可以看到裏面只有myMethod的,你會準備你的第二個參數如下所示:

val toUse = b.getOrElse(30) 

最後又用清楚地表達參數調用你的方法:

myMethodInternal(a,toUse) 
相關問題