Swift 3.0のRangeまとめ

  • 22
    いいね
  • 4
    コメント

Swift3.0でSwift2.2までのRangeと仕様が変わりました。
日本語ドキュメントが少なくSwift3へのマイグレーションに迷った部分があるので、まとめておきます。
Xcode 8.0 beta6で確認しています。

サマリ

Swift2.2からの変化

閉区間

Swift2.2ではRangeは開区間のみの表現となっていましたが、3.0で閉区間の実装が追加されています。

let x = 1...10

上のコードで初期化すると下記の様な違いが出ます。Swiftユーザには2.2までの仕様はよく知られたものだと思いますが、3.0で閉区間が実装され仕様変更されています。
また、閉区間の実装に合わせてstartIndex、endIndexの挙動が変わります。
これまでは閉区間でも開区間でも、Range<T>のTで取得できましたが、3.0からはClosedRangeIndex<T>という型の構造体が返却されます。
T型で値を取得する場合は、これまでの取得方法に変わり、Boundプロパティで取得できます。

- 2.2 3.0
Range<Int> CountableClosedRange<Int>
1..<11 1...10
count 10 10
startIndex 1 ClosedRangeIndex<T>
endIndex 11 ClosedRangeIndex<T>
upperBound - 1
lowerBound - 10

このClosedRangeIndex<T>への操作方法は追々細かく見ていこうと思います。
公式ドキュメントはここ

開区間

let x = 1..<10

開区間は型の変更のみで、初期化される値や取得できる値に変更はありません。

- 2.2 3.0
Range<Int> CountableRange<Int>
1..<10 1..<10
count 9 9
startIndex 1 1
endIndex 10 10
upperBound - 1
lowerBound - 10

CountableじゃないRange

Countableじゃないものも用意されているので一応紹介しておきます。

let x = ClosedRange(uncheckedBounds: (1, 10))
let y = Range(uncheckedBounds: (1, 10))

特に気をつけなければいけないのは、同じ型名でもSwift3.0ではRangeがSequenceプロトコルに準拠しないようになっているため、for-inやforEachで使えなくなっています。意識して使い分ける必要があります。