Swift 数组[index]没有';不返回可选的?
我觉得Swift 数组[index]没有';不返回可选的?,swift,Swift,我觉得array[index]应该返回一个可选的,因为索引可能超出范围 这将允许使用以下代码: 如果让对象=数组[索引]{ //做事 } 使用扩展方法很容易做到这一点,但了解这种情况的真正原因将是一件好事。 它取决于数组元素的类型。例如,如果将数组定义为 var arr:[String?] = Array<String?>(count: 5, repeatedValue: "SomeString") var arr:[String?]=数组(计数:5,repeatedValue:“
array[index]
应该返回一个可选的,因为索引可能超出范围
这将允许使用以下代码:
如果让对象=数组[索引]{
//做事
}
使用扩展方法很容易做到这一点,但了解这种情况的真正原因将是一件好事。
它取决于数组元素的类型。例如,如果将数组定义为
var arr:[String?] = Array<String?>(count: 5, repeatedValue: "SomeString")
var arr:[String?]=数组(计数:5,repeatedValue:“SomeString”)
然后,array[index]
将是可选的
但本质上,
array[index]
是一个非可选值,因为访问其边界之外的数组本身会引发异常,更不用说获取其值了。因此,您不会忽略阅读元素本身。这可能是出于设计。由于很容易获得数组中的项数,如果您从0迭代到count-1
,则始终会有一个值。如果array[index]
可以返回nil,那么每次遍历数组时都必须打开一个可选项,这将是一件痛苦的事情:)。这是其中之一,它被关闭为“行为正确”。还讨论了它。正如Dave Abrahams所指出的:
至于基本原理,很容易也很常见的静态知识是索引在范围内。。。。在这种情况下,最好建立一个前提条件,即索引是有效的,这样普通用例就不必在语法上处理不可能发生的故障。这与对键进行字典索引形成对比,通常不知道键是否已经在字典中
随着我在Swift方面的经验越来越丰富,我逐渐同意了这一点。有时我确实希望有一个内置的“安全下标”(比如),但我同意它不应该是默认值
将其设为默认值将使数组非常难以使用,这不仅是因为需要展开,还因为索引类型将不再是Int
。要求下标(索引)
返回元素
(不是元素?
)。这就是为什么字典的索引不是键的原因;它是字典索引
。创建一个特殊的ArrayIndex
可能会有很多恼人的副作用。(也许最终一切都会成功,但是否值得值得值得怀疑。)
这里真正的教训是,无论如何都应该避免任意订阅数组。如果可行,您应该更愿意将其用作集合类型
。这意味着只订阅您获取的索引(例如使用indexOf
或indexOf
),并且强烈支持迭代(对于in
,map
),而不是订阅。首先使用xs.first
而不是xs[0]
。如果将其视为一个集合而不是数组,则可以获得所描述的安全性,同时在需要解决知道下标在范围内的特殊问题时,仍保留可用下标
这里有一个说明性的例子。考虑这个常见的循环,您可能认为需要下标:
let xs = [1,2,3]
for i in 0..<xs.count {
print("\(i): \(xs[i])")
}
但即使这样也没有必要。我们可以做得更好,使其适用于所有序列:
for (i, x) in xs.enumerate() {
print("\(i): \(x)")
}
不需要下标。请尝试查看以下示例:
var-arr:Array=[]
arr.append(1)
arr.append(无)
arr.count==2
设n=arr[1]//nil
我认为用这个例子很容易理解原因。即使您的索引有效,您仍然会收到nil
因此,我们知道类型,但是:
如果让n=arr[1]{
//如何知道索引是否超出范围
//还是返回了有效的nil值?
}
考虑到user3441734:s答案下的详尽讨论(我们可能应该在chat中使用…),我觉得我必须澄清我认为user3441734试图表达的有点确定的观点
首先,请注意,问题包括
- Swift让无效索引情况像这样运行(抛出异常,超出范围),而不是返回可选索引的原因是什么
- 如果索引超出范围,是否可以获取可选的而不是异常
因此,现在让我们来看看用户3441734:s的答案,并尝试让它更清楚地告诉我们他/她试图指出什么 我们将分析以下表达式,假设我们处于一个平行的Swift宇宙中,其中无效索引情况(w.r.t.数组)被视为可选,并返回
nil
// Lets assume the following is all in the scope of some function
var arr: Array<Int?> = []
arr.append(1)
arr.append(nil)
arr.append(3)
print("\(arr)") // Optional(1), nil, Optional(3)
// lets say the function randomIntegerTwoOrFour() -> Int returns,
// randomly, either value 2 or value 4.
let ourMagicAndAtCompileTimeUnknownIndex = randomIntegerTwoOrFour()
// now, in our parallel Swift universe, say we want to
// use an if let clause on our array at our magic index
if let n = arr[ourMagicAndAtCompileTimeUnknownIndex] {
// ...
}
else {
// lets say we're not careful here, and think that we've
// entered this clause because of a nil valued member of
// our array. If we try to use our magic index for non-nil
// assignment, how would parallel universe Swift 2 handle this?
// We could of course try some downcasting to infer actual,
// (optional) type ourselves, but this is not very "Swifty"
// w.r.t. if let clauses.
}
// on the other hand, say we want to guard against invalid-index
// in our array, using a guard let clause
guard let n = arr[ourMagicAndAtCompileTimeUnknownIndex] else {
print("Out of bounds!")
// or are we ...? Careful parallel Swift universe programmer!
// Naturally, we could (and should, in parallel Swift 2 universe),
// look closer at what type n is at this point, but this is also
// not very "Swifty" in this context).
return
}
//假设以下内容都在某个函数的范围内
var arr:Array=[]
arr.append(1)
arr.append(无)
附件(3)
打印(\(arr)//可选(1)、无、可选(3)
//假设函数randomIntegerTwoOrFour()->Int返回,
//随机选择值2或值4。
让我们的magicanDatCompileTimeUnknownIndex=randomIntegerTwoOrFour()
//现在,在我们平行的迅捷宇宙中,我们想
//在我们的魔术索引数组上使用if-let子句
如果让n=arr[ourmagicandatcomiletimeunknownindex]{
// ...
}
否则{
//假设我们在这里不小心,并认为我们
//由于无值成员而输入此子句
// Lets assume the following is all in the scope of some function
var arr: Array<Int?> = []
arr.append(1)
arr.append(nil)
arr.append(3)
print("\(arr)") // Optional(1), nil, Optional(3)
// lets say the function randomIntegerTwoOrFour() -> Int returns,
// randomly, either value 2 or value 4.
let ourMagicAndAtCompileTimeUnknownIndex = randomIntegerTwoOrFour()
// now, in our parallel Swift universe, say we want to
// use an if let clause on our array at our magic index
if let n = arr[ourMagicAndAtCompileTimeUnknownIndex] {
// ...
}
else {
// lets say we're not careful here, and think that we've
// entered this clause because of a nil valued member of
// our array. If we try to use our magic index for non-nil
// assignment, how would parallel universe Swift 2 handle this?
// We could of course try some downcasting to infer actual,
// (optional) type ourselves, but this is not very "Swifty"
// w.r.t. if let clauses.
}
// on the other hand, say we want to guard against invalid-index
// in our array, using a guard let clause
guard let n = arr[ourMagicAndAtCompileTimeUnknownIndex] else {
print("Out of bounds!")
// or are we ...? Careful parallel Swift universe programmer!
// Naturally, we could (and should, in parallel Swift 2 universe),
// look closer at what type n is at this point, but this is also
// not very "Swifty" in this context).
return
}