2012-09-01 116 views
1

右切正題隱含斯卡拉錯誤還是我?

「轉換」 詮釋爲String

implicit def int2string(i: Int): String = { 
    "foo" 
    } 

方法,需要一個String和打印

def printString(i: String) = print(i) 

調用PRINTSTRING與int參數

printString(_:Int) 

不應該顯示「富」嗎?但是printString(i:String)永遠不會被調用。

printString(1)版畫「富」

這裏有一個問題,或者我失去了一些東西?

回答

6

這是因爲什麼printString(_:Int)實際上它的作用是將在需要詮釋,也許永遠不會調用的函數表達式...查看:

scala> implicit def int2string(i: Int): String = "foo" 
int2string: (i: Int)String 

scala> def printString(i: String) = print(i) 
printString: (i: String)Unit 

這裏沒有語法錯誤意味着它正在發揮作用。作爲一種說明:

scala> printString(_:Int)  // Function from Int to Unit 
res0: Int => Unit = <function1> 

編譯器轉動外表達成{ x:Int => printString(x) },然後由於隱式是在範圍上施加的隱式轉換的,所以結果是{ x:Int => printString(int2string(x)) }

非工作之一,因爲沒有轉換,從對象到字符串:

scala> printString(_:Object) 
<console>:10: error: type mismatch; 
found : java.lang.Object 
required: String 
       printString(_:Object) 

我們實際看到的,我們需要調用它的打印:

scala> val foo = printString(_:Int) 
foo: Int => Unit = <function1> 

scala> foo(5) 
foo 
+0

是的。但是再次確定printString獲取一個String參數,而不是(Int)=> String。 隱式int2String允許scala編譯尚未printString(i:Int => String)來調用。這不是那種奇怪的行爲嗎? – weakwire

+0

不,不是。你錯過了這裏的觀點。我會盡力改進這裏的解釋。 – pedrofurla

+0

這正是使用for的隱式轉換,你有一個Int類型的變量,但是當你把它賦給一個函數時,你希望它轉換爲String。所以你定義了一個讓隱含的def來讓Scala爲你做所有這些工作。對我來說很合理。 –

1

以下斯卡拉REPL幾乎講述了整個故事,它永遠不會被調用是因爲printString(_:Int)不是一個函數調用。您正在創建一個新功能。

如果您直接傳入int,則一切正常。

scala> implicit def int2string(i: Int): String = { 
    |  "foo" 
    | } 
int2string: (i: Int)String 

scala> def printString(i: String) = print(i) 
printString: (i: String)Unit 

scala> val x = printString(_:Int) 
x: Int => Unit = <function1> 

scala> x(10) 
foo 

// This works because you have implicit def, 
// and this will be printString(int2string(10)) 
// when your argument is a Int. 
scala> printString(10) 
foo 
scala> 
+0

下添加另一個段落感謝您的澄清 – weakwire