2016-02-13 197 views
0

我嘗試寫一些代碼轉換的隱含參數,喜歡的隱式轉換如下:斯卡拉隱含參數

case class A() 
case class B() 
object B { 
    implicit def b2a(b: B): A = new A() 
} 

def foo(f: B => String) = f(new B()) 
def bar(implicit a: A) = "A" 

foo { implicit b => 
    bar() 
} 

給出了錯誤:

<console>:27: error: not enough arguments for method bar: (implicit a: A)String. 
Unspecified value parameter a. 

有沒有一種辦法使用隱式轉換而不手動調用它?

+1

這不是一個答案,但你絕對肯定你需要這樣做嗎?你已經看到了一個令人困惑的混亂情況,那就是不得不推斷這些暗示將如何解決 - 你是否真的想對每個使用你的代碼的人強加這種困惑? –

+0

我同意。這比它值得的更麻煩,但我接受了@ m-z的回答,因爲它解決了這個問題。 – pschorf

回答

2

我相信這打破了「一次一個」的規則。在您致電bar的範圍內沒有隱含的A,只有隱含的B。如果編譯器試圖隱式地將隱式B轉換爲A,那將是兩個步驟,而不是一個步驟。

但是,您可以通過隱式鏈接解決此問題。

implicit def a(implicit b: B): A = new A() 

如果此方法是在範圍內,則編譯器將看到在範圍的隱式A,只要它可以填充隱B,它可以。

scala> foo { implicit b => bar } 
res1: String = A 

你遇到的具體錯誤是因爲你需要刪除括號,我在這裏做了。這會導致上述的「隱含未找到」錯誤。

+0

可以通過將它放入「A」而不是「B」的伴隨對象來使其始終處於範圍內。 – Kolmar

+0

'「一次一個」規則「 - 你能否提供一個鏈接,m-z? –

+0

@KevinMeredith [Odersky,Spoon和Venners在Scala 21.2中編程](https://www.artima.com/pins1ed/implicit-conversions-and-parameters.html#21.2) –