在Swift标准库中触发运行时错误

Array.swift

Using a negative number or an index equal to or greater than count triggers a runtime error.

使用负数或大于等于count的索引会触发运行时错误。

1
print(emptyDoubles[0])

ClosedRange.swift

An equivalent range must be representable as a closed range. For example, passing an empty range as other triggers a runtime error, because an empty range cannot be represented by a closed range instance.

等效范围必须可以表示为闭合范围。例如,将空范围作为 other 传递会触发运行时错误,因为空范围不能由封闭范围实例表示。

1
2
let emptyRange = 0..<0
ClosedRange(emptyRange)

Dictionary.swift

Passing a sequence with duplicate keys to this initializer results in a runtime error. If your sequence might have duplicate keys, use the Dictionary(_:uniquingKeysWith:) initializer instead.

向此构造器传递具有重复键的序列会导致运行时错误。如果序列可能有重复的键,则使用Dictionary(_:uniquingKeysWith:) 初始化。

1
2
3
let digitWords = ["one", "two", "three", "four", "five"]
let wordToValue = Dictionary(uniqueKeysWithValues: zip(digitWords, 1 ... 5))
let wordToValueAndRemoveDuplicateKeys = Dictionary(zip(["one", "one", "three", "four", "five"], 1 ... 5)) { max($0, $1) }

DictionaryCasting.swift

1
2
var dic: [String: Any] = ["name": "li", "age": 18]
dic as! [String: String]

Integers.swift

When the additive inverse of a value is unrepresentable in a conforming type, the operation should either trap or return an exceptional value. For example, using the negation operator (prefix -) with Int.min results in a runtime error.

当一个值的负值在一个符合类型中不可表示时,操作应该捕获或返回一个异常值。例如,将否定运算符(前缀-)与 Int.min一起使用会导致运行时错误。

1
2
3
4
5
6
7
8
9
10
11
12
13
let x = Int.min
let y = -x
// Overflow error

let z = -Int8.min
// Overflow error

var y = Int8.min
y.negate()
// Overflow error

let z = UInt32(-500)
// Error

Optional.swift

In debug builds (-Onone), the unsafelyUnwrapped property has the same behavior as using the postfix ! operator and triggers a runtime error if the instance is nil.

在调试版本(-Onone)中,unsafelyUnwrapped属性的行为与使用后缀的行为相同!如果实例为 nil ,则触发运行时错误。谨慎使用

1
2
3
let optionalInt: Int? = nil
optionalInt.unsafelyUnwrapped
optionalInt!

Policy.swift

If you have prior knowledge that an AnyObject instance has a particular type, you can use the unconditional downcast operator (as!). Performing an invalid cast triggers a runtime error.

如果您事先知道AnyObject实例具有特定的类型,则可以使用无条件向下转换运算符(as)。 执行无效强制转换会触发运行时错误。

1
2
3
4
5
let message = s as! String
print("Successful cast to String: \(message)")
// Prints "Successful cast to String: This is a bridged string."
let badCase = v as! String
// Runtime error

Range.swift

An equivalent range must be representable as an instance of Range. For example, passing a closed range with an upper bound of Int.max triggers a runtime error, because the resulting half-open range would require an upper bound of Int.max + 1, which is not representable as

范围边界值越界会触发运行时错误,如设置最大值为Int.max时。

1
Range(0 ... Int.max)

Always use the slice’s startIndex property instead of assuming that its indices start at a particular value. Attempting to access an element by using an index outside the bounds of the slice’s indices may result in a runtime error, even if that index is valid for the original collection.

始终使用 slice 的startIndex属性,而不是假设它的索引以特定的值开始。试图通过在slice索引的边界之外使用索引来访问元素可能会导致运行时错误,即使该索引对原始集合有效。

1
2
3
4
5
6
7
8
9
10
11
let streets = ["Adams", "Bryant", "Channing", "Douglas", "Evarts"]
let streetsSlice = streets[2...]
print(streetsSlice)
// ["Channing", "Douglas", "Evarts"]

print(streetsSlice.startIndex)
// 2
print(streetsSlice[2])
// "Channing"
print(streetsSlice[0])
// error: Index out of bounds

RangeReplaceableCollection.swift

Attempting to remove more elements than exist in the collection triggers a runtime error.

尝试移除集合中存在的元素数目多于存在的元素会触发运行时错误。

1
2
3
var array = Array(0 ..< 5)
array.removeFirst(6)
array.removeLast(6)

SetCasting.swift

We can’t just delegate to _setDownCastConditional here because we rely on as! to generate nice runtime errors when the downcast fails.

Set 向下强制转换失败时,会产生运行时错误。

1
2
var s: Set<AnyHashable> = [1, 2, "3"]
s as! Set<Int>

StaticString.swift

1
2
3
4
5
6
7
8
9
10
11
// * a pointer to a null-terminated sequence of UTF-8 code units:
let emoji: StaticString = "\u{1F600}"
emoji.hasPointerRepresentation // -> true
emoji.isASCII // -> false
// emoji.unicodeScalar // -> Fatal error!
emoji.utf8CodeUnitCount // -> 4
emoji.utf8Start[0] // -> 0xF0
emoji.utf8Start[1] // -> 0x9F
emoji.utf8Start[2] // -> 0x98
emoji.utf8Start[3] // -> 0x80
emoji.utf8Start[4] // -> 0x00
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// * a single Unicode scalar value, under very limited circumstances:
struct MyStaticScalar: ExpressibleByUnicodeScalarLiteral {
typealias UnicodeScalarLiteralType = StaticString
let value: StaticString
init(unicodeScalarLiteral value: StaticString) {
self.value = value
}
}

let emoji: StaticString = MyStaticScalar("\u{1F600}").value
emoji.hasPointerRepresentation // -> false
emoji.isASCII // -> false
emoji.unicodeScalar.value // -> 0x1F600
emoji.utf8CodeUnitCount // -> Fatal error!
emoji.utf8Start // -> Fatal error!

hasPointerRepresentation 一个布尔值,表示静态字符串是否存储指向以 null 结尾的 UTF-8代码单元序列的指针。

  • true:这时访问unicodeScalar会触发运行时错误;
  • false:静态字符串存储单个 Unicode 标量值。这时访问utf8开头的属性会触发运行时错误;