Swift3.0でSwift2.2までのRangeと仕様が変わりました。
日本語ドキュメントが少なくSwift3へのマイグレーションに迷った部分があるので、まとめておきます。
Xcode 8.0 beta6で確認しています。
サマリ
- Proposal: A New Model for Collections and Indices
- 閉区間が実装された
- 端の値はBoundで取得する
- 同じ型名(Range)でもSwift3.0ではfor-inとかで使えない
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>
への操作方法は追々細かく見ていこうと思います。
公式ドキュメントは[ここ] (https://developer.apple.com/reference/swift/countableclosedrange)。
開区間
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で使えなくなっています。意識して使い分ける必要があります。