2016-08-11 49 views
2

也許這是一個Xcode 8測試版的問題,但是,之前2.2 var關鍵字可以在函數簽名前面加上參數:如何用Swift> 2.2在閉包中表示可變參數?

func (var stringName: String) { ... } 

這已經被超過inout棄用代替那裏是沒有什麼好處

func (stringName: inout String) { ... } 

我已經嘗試在map封閉以下,雖然我沒有收到折舊警告爲輕度預期我應該,錯誤是個相當segmentation fault: 11

let demoString = ["hi", "there", "world"].map { (var word) -> String in 
    let firstChar = word.remove(at: word.startIndex) 
} 

只要我試圖突變(假設可變)word變量,就會報錯。

我試過其他的變化例如使用inout

let demoString = ["hi", "there", "world"].map { (word: inout String) -> String in 
    let firstChar = word.remove(at: word.startIndex) 
} 

但是編譯器會抱怨,這錯誤地改變了封閉的完全的簽名,將無法編譯。

顯然,解決辦法很簡單,就是封閉內變量複製到本地一個:

let demoString = ["hi", "there", "world"].map { (word) -> String in 
    let tempWord = word 
    let firstChar = tempWord.remove(at: tempWord.startIndex) 
} 

不過,我想知道,如果這種預期的功能&是否存在的一種方式突變直接傳遞給閉包的參數?

+0

貴的問題得到解答? – Alexander

回答

3

閉包可以發生變異inout參數就好了:

var str1 = "Pine" 
var str2 = "Juniper" 

let closure = { (s1: inout String, s2: inout String) -> Void in 
    s1 = "Oak" 
    s2 = "Chestnut" 
} 

closure(&str1, &str2) 

print(str1, str2) 

你所面對的問題是Array.map不有一個方法簽名,其中包含inout參數。

解決這個,我能想到的唯一的辦法是延長陣列,並添加map方法自己:

extension Array { 
    func map<T>(_ closure: (inout T) -> Void) -> Array<T> { 
     var arr = [T]() 
     for i in 0..<self.count { 
      var temp : T = self[i] as! T 
      closure(&temp) 
      arr.append(temp) 
     } 
     return arr 
    } 
} 

var hi = "hi", there = "there", world = "world" 
var demoStrings = [hi, there, world] 
var result = demoStrings.map { (word: inout String) in 
    word.remove(at: word.startIndex) 
} 

print(result) // ["i", "here", "orld"] 
0

SE-0003var參數斯威夫特不復存在3.

從根本上說,你不應該從突變給出map的參數,反正。相反:使用非變異函數,或製作一個本地可變副本。

在這種情況下,沒有理由僅使用remove(_:)來獲取第一個字符。這需要複製一個字符串的內存(省略第一個字符),僅僅爲了得到被刪除的字符。它非常笨重。

在這種情況下,你可以得到的Stringcharacters實例屬性的first實例變量(從Collection協議)。

試試這個:

let demoStrings = ["hi", "there", "world"] 

let firstLetters = demoStrings.map {(word: String) -> String in 
    return word.characters.first 
} 

或簡稱:

let firstLetters = demoStrings.map{ $0.characters.first } 
+0

感謝您的評論。我實際上並不是在尋找重寫表達式的方法。它只是用於演示目的。我試圖找出傳遞給閉包的參數是否可以發生變化。如果你需要的只是第一個字母,請用FYI'word.characters.first'。 –

+0

當然,我不知道爲什麼'.first'沒有想到爲什麼lol – Alexander

+0

你可以用'inout'參數關閉,但是你不能爲'map'使用這樣一個閉包,因爲聲明map的閉包(它不使用'inout') – Alexander

相關問題