1.はじめに
今回は範囲型ともう一つの基本的なデータ型である、ストライド型について解説します。前回の記事では範囲型のことを解説しており、今回の記事とつながりがある内容なので、見てない方はお時間ありましたら是非ご覧ください。
URL(https://qiita.com/0901_yasyun/items/0e86c602ddff1c472786)
2.ストライド型とは
ストライド型とは、整数や実数などの比較できる値に対して、開始点と終了点、刻み幅から構成される構造体のことを指します。開始点から終了点まで、刻み幅ごとに値を取り出すことができます。
ストライド型には2種類あり、StrideThrough型とStrideTo型があります。それぞれの方のインスタンスは、標準ライブラリの次の関数を使って生成できます。型Tは実際に因数に指定して型によって決まります。
func stride(from: T, through: T, by: T.Stride) -> StrideThrough<T>
func stride(from: T, to: T, by: T.Stride) -> StrideTo<T>
3.StrideTo型
関数strideはfor-in文と一緒によく使われるので、その一例を以下に示します。
for x in stride(from:0, to:20, by:2){ // 0から20の直前まで2刻みで
print(x, terminator:" ")
}
print() // "0 2 4 6 8 10 12 14 16 18 "と表示する
このように、fromで指定した値からtoで指定した値まで、byで指定した値で刻みながらループしていることが分かります。しかしここで注目してほしいのは、最後の数が18であるという点です。このようにStrideTo型は、順番に取り出した最後の値が終了点の値と一致した場合、その値は採用しません。
4.StrideThrough型
一方、StrideThrough型は終了点の値も含みます。実数を使った例を以下に示します。
for x in stride(from:1.0, through:0.0, by:-0.2){ // 1.0から0.0のまで-0.2刻みで
print(x, terminator:" ")
}
print() // "1.0 0.8 0.6 0.4 0.2 0.0 "と表示する
このように、StrideThrough型をfor-in文で使った場合、終了点の値も含むことが分かります。ただし、刻み幅を使って増加、減少させていくので、必ずしも最後の値が終了点と同じになるとは限りません。また実数の場合には誤差が伴うので、加算していっても終了点の値と一致しないこともあります。
5.プロトコルStrideable型
ここでストライド型の引数の型について説明します。関数Stride(from: to: by:)の場合、宣言は正確に書くと以下のようになります。
func stride<T>(from:T, to:T, by:T.Stride) -> StrideTo<T>
where T : Strideable
Tは型パラメータです。where T: Strideableの部分は、型TはプロトコルStrideable型に適合していなければいけないという制約を表しています。
プロトコルStrideable型にもきちんとした定義内容がありますが、若干主旨からずれてしまうのと、まだ私が記事で説明していない内容が出てくるなど、少し複雑な話になってしまうので、今回具体的な定義内容は省略します。
しかし、ストライド型を使ううえでプロトコルStrideable型が、見えないところで内部的に関わっているということだけ、頭の片隅に置いておきましょう。
6.おわりに
今回は前回に引き続き、範囲型ともう一つの基本的なデータ型であるストライド型について、簡単に解説しました。データ型は様々なコードを書く上で、効果的に使える場面が多々あると思います。経験を積むだけどんどん効果的に利用できるようになると思うので、積極的に使っていきましょう。