3 回答

TA貢獻(xiàn)1865條經(jīng)驗(yàn) 獲得超7個(gè)贊
我偶然發(fā)現(xiàn)了一種更好的實(shí)現(xiàn)此功能的方法:
Swift 3.2和更新版本
extension Collection { /// Returns the element at the specified index if it is within bounds, otherwise nil. subscript (safe index: Index) -> Element? { return indices.contains(index) ? self[index] : nil }}
Swift 3.0和3.1
extension Collection where Indices.Iterator.Element == Index { /// Returns the element at the specified index if it is within bounds, otherwise nil. subscript (safe index: Index) -> Generator.Element? { return indices.contains(index) ? self[index] : nil }}
斯威夫特2
extension CollectionType { /// Returns the element at the specified index if it is within bounds, otherwise nil. subscript (safe index: Index) -> Generator.Element? { return indices.contains(index) ? self[index] : nil }}
例
let array = [1, 2, 3]for index in -20...20 { if let item = array[safe: index] { print(item) }}

TA貢獻(xiàn)2019條經(jīng)驗(yàn) 獲得超9個(gè)贊
如果你真的想要這種行為,它就像你想要一個(gè)Dictionary而不是一個(gè)數(shù)組。字典nil
在訪問丟失的密鑰時(shí)返回,這是有道理的,因?yàn)橐烂荑€是否存在于字典中要困難得多,因?yàn)檫@些密鑰可以是任何東西,在數(shù)組中密鑰必須在以下范圍內(nèi):0
to count
。迭代這個(gè)范圍是非常常見的,你可以絕對(duì)肯定在循環(huán)的每次迭代中都有一個(gè)真正的值。
我認(rèn)為它不能以這種方式工作的原因是Swift開發(fā)人員做出的設(shè)計(jì)選擇。舉個(gè)例子:
var fruits: [String] = ["Apple", "Banana", "Coconut"]var str: String = "I ate a \( fruits[0] )"
如果您已經(jīng)知道索引存在,就像在大多數(shù)使用數(shù)組的情況下一樣,這段代碼很棒。但是,如果訪問標(biāo)可能可能返回nil
,那么你已經(jīng)改變了返回類型的Array
的subscript
方法是可選的。這會(huì)將您的代碼更改為:
var fruits: [String] = ["Apple", "Banana", "Coconut"]var str: String = "I ate a \( fruits[0]! )"// ^ Added
這意味著每次迭代數(shù)組時(shí)都需要解包一個(gè)可選項(xiàng),或者使用已知索引執(zhí)行任何其他操作,因?yàn)楹苌儆腥丝梢栽L問超出范圍的索引。Swift設(shè)計(jì)者在訪問越界索引時(shí)以犧牲運(yùn)行時(shí)異常為代價(jià),選擇了較少的可選解包。崩潰比nil
你在某個(gè)地方?jīng)]想到的邏輯錯(cuò)誤更可取。
我同意他們的觀點(diǎn)。因此,您將不會(huì)更改默認(rèn)Array
實(shí)現(xiàn),因?yàn)槟鷮⑵茐乃行枰獊碜詳?shù)組的非可選值的代碼。
相反,您可以子類化Array
,并覆蓋subscript
以返回可選項(xiàng)?;蛘撸鼘?shí)際地,您可以Array
使用執(zhí)行此操作的非下標(biāo)方法進(jìn)行擴(kuò)展。
extension Array { // Safely lookup an index that might be out of bounds, // returning nil if it does not exist func get(index: Int) -> T? { if 0 <= index && index < count { return self[index] } else { return nil } }}var fruits: [String] = ["Apple", "Banana", "Coconut"]if let fruit = fruits.get(1) { print("I ate a \( fruit )") // I ate a Banana}if let fruit = fruits.get(3) { print("I ate a \( fruit )") // never runs, get returned nil}
Swift 3更新
func get(index: Int) ->
T?
需要被替換 func get(index: Int) ->
Element?
- 3 回答
- 0 關(guān)注
- 675 瀏覽
添加回答
舉報(bào)