我在scalaLang的twitter上發現了一個有趣的帖子。這個代碼編譯和工作的地方用scalaLang在scala中定義一個變量
class A(implicit implicit val b: Int)
val objA = new A()(42)
有人可以請解釋我是如何工作的?我讀了implicits的文檔,但沒有發現這樣的情況。請解釋我在這裏發生了什麼。
任何幫助表示讚賞!
我在scalaLang的twitter上發現了一個有趣的帖子。這個代碼編譯和工作的地方用scalaLang在scala中定義一個變量
class A(implicit implicit val b: Int)
val objA = new A()(42)
有人可以請解釋我是如何工作的?我讀了implicits的文檔,但沒有發現這樣的情況。請解釋我在這裏發生了什麼。
任何幫助表示讚賞!
您可以在類或方法的最後一個參數列表之前以及類或特徵的任何成員之前有implicit
。這簡單地將兩者結合起來,這可能是合法的,因爲禁止它會使語言規範和解析器稍微複雜一點,而沒有真正的好處。我認爲沒有任何理由可以使用這個或任何一次寫implicit
的區別。
經過一番挖掘,我確認@Alexey Romanov說了些什麼。考慮下面的例子:
case class A(implicit implicit val a: Int)
def foo(x: Int)(implicit y: Int): Int = x * y
我們可以用這樣的:
implicit val m: Int = 2
val myA = A()
及以下應用:
val myAA = A()(2)
val n = myAA.a
foo(3)
現在,foo(3)
明顯得到6,因爲它需要n
含蓄。如果我們改變了類
case class A(implicit val a: Int)
它不會改變的foo
行爲。因此,我們得出的結論相同:@Alexey - 第一個implicit
表示構造函數參數可以隱式傳遞;而第二個定義隱式值 - 即使在這種情況下,他們也是這樣做的。
糾正我,如果我錯了,但'foo'暗含'm',它隱藏的事實是'n == m'。 'n'沒有被聲明爲隱含的,所以它不能被這樣使用,而且如果你聲明同一個作用域中隱含的兩個相同類型的值,那麼編譯器會因爲含糊性而引起錯誤 –
你是對的。我從IDE複製了一段錯誤的代碼。我會更新答案。編輯:更新。 – sebszyller