Swift

Swift 3.0のRangeまとめ

More than 1 year has passed since last update.

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で使えなくなっています。意識して使い分ける必要があります。