2015-09-11 26 views

回答

5

這裏的問題是存在的錯誤消息。一般來說,當你看到類似cannot invoke .. with ...這意味着編譯器的類型推斷剛剛沒有工作。

在這種情況下,您遇到了關閉中推斷的侷限性之一。 Swift只能推斷出單個語句的類型,而不是多語句的類型。在你的第一個例子:

arr.map() { 
    x in 
    return x + 2 
} 

有實際上是隻有一個語句:return x + 2。然而,在第二:

arr.map() { 
    x in 
    var y = x + 2 
    return y 
} 

有一個賦值語句(var y = x + 2),並然後回報。所以這個錯誤有點誤導:它並不意味着你「不能用這種類型的參數調用map()」,它的意思是說「我找不出什麼類型的x或y是什麼」。

順便說一句,在單語句閉包中,還有兩件事情可以推斷出來。 return語句:

arr.map() { 
    x in 
    x + 2 
} 

和變量名本身:

arr.map() { $0 + 2 } 

這一切都產生相同的編譯代碼,但。所以這是你選擇的一個品味的問題。 (例如,雖然我認爲推斷return看起來乾淨,更容易閱讀,但我不知道$0那樣,所以我通常總是會把x in什麼東西,即使是非常短的封閉也是如此,這取決於你。)

的最後一件事:因爲這是一切真的只是語法的東西,這是值得注意的是,不需要()之一:

arr.map { x in x + 2 } 

由於@MartinR指出,編譯器可以推斷出某些類型從外部環境來看:

let b: [Int] = arr.map { x in 
    var y = x + 2 
    return y 
} 

這值得銘記。(it seems that the "one-statement" rule only applies when there's no other type info available

+2

小增加:編譯器可以從* outer context *:'let b:[Int] = arr.map {x in var y = x + 2;}中推斷出閉包的返回類型。返回y}'。 –

+0

對不起,必須接受Zoff的回答,他是第一個 – user1284151

5

斯威夫特無法推斷類型的每個時間。即使它應該看到y = x + 2意味着y也是Int。我的猜測是,Swift按照某種順序解析閉包,使得它不會提前知道返回類型。

這工作:

arr.map() { 
    x -> Int in 
    var y = x + 2 
    return y 
} 
+0

是的,這實際上解決了如何解決這個問題。謝謝! – DonnaLea

相關問題