3 回答

TA貢獻1865條經驗 獲得超7個贊
我偶然發現了一種更好的實現此功能的方法:
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貢獻2019條經驗 獲得超9個贊
如果你真的想要這種行為,它就像你想要一個Dictionary而不是一個數組。字典nil
在訪問丟失的密鑰時返回,這是有道理的,因為要知道密鑰是否存在于字典中要困難得多,因為這些密鑰可以是任何東西,在數組中密鑰必須在以下范圍內:0
to count
。迭代這個范圍是非常常見的,你可以絕對肯定在循環的每次迭代中都有一個真正的值。
我認為它不能以這種方式工作的原因是Swift開發人員做出的設計選擇。舉個例子:
var fruits: [String] = ["Apple", "Banana", "Coconut"]var str: String = "I ate a \( fruits[0] )"
如果您已經知道索引存在,就像在大多數使用數組的情況下一樣,這段代碼很棒。但是,如果訪問標可能可能返回nil
,那么你已經改變了返回類型的Array
的subscript
方法是可選的。這會將您的代碼更改為:
var fruits: [String] = ["Apple", "Banana", "Coconut"]var str: String = "I ate a \( fruits[0]! )"// ^ Added
這意味著每次迭代數組時都需要解包一個可選項,或者使用已知索引執行任何其他操作,因為很少有人可以訪問超出范圍的索引。Swift設計者在訪問越界索引時以犧牲運行時異常為代價,選擇了較少的可選解包。崩潰比nil
你在某個地方沒想到的邏輯錯誤更可取。
我同意他們的觀點。因此,您將不會更改默認Array
實現,因為您將破壞所有需要來自數組的非可選值的代碼。
相反,您可以子類化Array
,并覆蓋subscript
以返回可選項。或者,更實際地,您可以Array
使用執行此操作的非下標方法進行擴展。
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 關注
- 676 瀏覽
添加回答
舉報