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在訪問丟失的密鑰時返回,這是有道理的,因為要知道密鑰是否存在于字典中要困難得多,因為這些密鑰可以是任何東西,在數組中密鑰必須在以下范圍內:0to 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 瀏覽
添加回答
舉報
