LoginSignup
5
5

More than 5 years have passed since last update.

Swiftで(guard節の中でも)配列の存在しないindexを参照するとクラッシュする

Last updated at Posted at 2017-01-24

コメントより (2017/01/25追記)

そもそも、arrayの範囲外インデックスへのアクセスはコードで回避する以前に設計の問題とのことです。
記事としての妥当性に欠けておりました、申し訳ありません。

Swift では、 Array のインデックスが範囲外の場合のエラーは、ハンドリングして処理すべきエラーではなくコーディングの誤りである( Logic failure )とみなされているので、そのようなケースを guard let や if let でハンドリングすることはできません。実行時にハンドリングするのではなくて、誤ったコードを修正すべきという考えです。 Array のインデックスが範囲外の場合にそれをハンドリングしたい具体的なユースケースを考えてみると、そんなケースはほとんど思いつかないので妥当な設計だと思います。

by @koher (Yuta Koshizawa) さん

以下元記事

「Xcodeに怒られなければいいよね :smile::gun: :cop:

Playground
var array: [String]?

array = ["first", "second", "third"]

func getStr(index: Int) -> String? {
    guard let str = array?[index] else { // 👈 ここでクラッシュ
        return nil
    }

    return str
}

print(getStr(index: 3)) // 👈 配列外を参照

fatal error: Index out of range

:fire:

:hospital: :mask:

Safe (bounds-checked) array lookup in Swift, through optional bindings?
http://stackoverflow.com/questions/25329186/safe-bounds-checked-array-lookup-in-swift-through-optional-bindings

Swift
extension Collection where Indices.Iterator.Element == Index {

    /// Returns the element at the specified index iff it is within bounds, otherwise nil.
    subscript (safe index: Index) -> Generator.Element? {
        return indices.contains(index) ? self[index] : nil
    }
}

👇

Swift
let array = [1, 2, 3]

for index in -20...20 {
    if let item = array[safe: index] {
        print(item)
    }
}
5
5
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5