本日も Swift の 演算子
まわりを見ていきますね。その中の 範囲演算子
のあたりから始めて、その次の大きく分けて3つの演算子のスタイルがある話あたりが、今回の話題になりそうです。よろしくお願いしますね。
———————————————————————————————————————— 熊谷さんのやさしい Swift 勉強会 #317
00:00 Start 01:56 範囲演算子 04:17 範囲の詳細な記述方法 04:50 範囲演算子の使いどころ 05:58 範囲表現は初期の Swift とは様変わりした印象 07:41 RangeReplaceableCollection と範囲との相性 13:39 そのほかの範囲の使い道 18:42 さまざまな範囲表現の型 21:30 大小関係を検査しないイニシャライザー 24:11 範囲の表現方法によって、上限や下限の有無が異なる 25:16 範囲表現は Range 型が基本 ————————————————————————————————————————
Transcription & Summarize : 熊谷さんのやさしい Swift 勉強会 #317
では、Swiftの範囲演算子について話を始めましょう。これまでの勉強会では、主にC言語でよく使われる演算子について改良された点を説明してきましたが、今日はC言語にはない、新しい演算子に注目していきたいと思います。
Swiftは、その設計思想の中で、C言語を少しライバルのように意識している部分があります。C言語は、プログラミングの世界で非常に重要で広く使われている言語で、多くの人にとって親しみ深いものだと思います。そのため、SwiftではC言語の良いところを取り入れつつ、より安全で使いやすい言語を目指しているのです。
今回紹介するのは、範囲を簡単に表現するためのSwiftの演算子です。たとえば、範囲を示すために A..<B
や A...B
という形で表現します。これは、非常に簡潔に範囲を示す方法であり、基本的に「省略記法」と言えるでしょう。
では、具体的にどのような場面で範囲演算子を使うことが多いのでしょうか。これは人それぞれですが、一般的には配列の部分取得や、ループでの回数指定など、幅広い場面で使われます。皆さんの中でも、特にどのような用途で使うのか具体的に考えてみると良いかもしれません。では、範囲演算子を使う際の具体的なコード例などを見ていきましょう。 それぞれのレンジについて考えるとき、自分の中では割とイメージできています。範囲を判定するときによく使うのは、if
文やswitch
文といったものです。ここでは、3つの範囲を指定してみましょう。範囲を示すための値を作る方法も重要です。想像しやすいのは、取り囲みとする数を指定して、クローズドレンジ型として作成する動きです。これが基本的な動作となります。
Swift 3以降では、レンジ型が大きく変化しました。当時はカウンタブルレンジといった、もう少し細かい型でレンジが表現されていましたが、現在はクローズドレンジやレンジなどが登場しています。レンジ型は複数存在しており、昔からSwiftを使ってレンジについて詳しく知っている人には、少し違った型が見えるかもしれません。
現在のSwiftでは、レンジエクスプレッションと呼ばれるプロトコルによって、異なる型を統一的に扱うことができます。その一つにレンジリプレイサブルコレクションというものがあります。これは、コレクションにおいてインデックスを範囲で指定して色々な操作が可能であり、これに準拠しています。
たとえば、数値が10から50まであるとして、範囲を5から7の間に絞ってみると、その範囲で指定した要素を取り扱うことができます。また、レンジリプレイサブルコレクションにおいては、要素範囲を指定して別の値に置き換えることも可能です。例えば、範囲の中に7を入れ替えることで、全体の構造を変えることなく、指定された箇所だけ変更することができます。
さらに、範囲を指定するアプローチの一つに、範囲を逆順にして要素を削除するという方法があります。これを用いると、削除後の構造が変わることによる問題を回避できます。ただし、この方法を知らなくても、インデックスの範囲を事前に用意しておくことで、コードを簡潔に書くこともできます。
コードを書く上での一つの方法として、ターゲットとなる要素を特定のインデックス範囲で指定し、それを消したりするというテクニックも存在します。このような作業は、特にレンジの扱いにおいて非常に便利です。 例えば、8から5のような範囲を指定すると、多分ランタイムエラーが起きてしまいます。実際に試すとランタイムエラーが発生しましたね。原因は、範囲の指定がローアバウンドとアッパーアバウンドの関係が逆になっているためです。この場合、絶対にエラーが生じます。
これはすべて応用に繋がる話です。例えば、ループを回す際、5から8まで繰り返す際に範囲を使います。今回は変数を使いましたが、リバースを使うことで範囲を逆にすることもできます。ただし、リバースにはバグが含まれることがあるので注意が必要です。それでも、範囲を利用してループを繰り返す方法は便利です。また、ベンチマークを取る時にも役立つことがあります。 Swiftの範囲の表現についてですが、まず基本的な使い方として、例えば「0から5未満まで」といった範囲を繰り返し処理することができます。Swiftでは、範囲演算子を使ってこのような繰り返しを簡潔に表現できます。
例えば、for i in 0..<5
のように書くと、iの値は0から4まで繰り返されます。一方、終端を含む場合には、1...10
のような記述を使用します。このように、Swiftの範囲は「..<」や「...」といった演算子を使って定義され、ある範囲内でループ処理を行うのに便利です。
また、範囲とスイッチ文を組み合わせると、複数のケースに対して範囲指定を用いた判定が可能です。これは範囲の便利な機能の一つで、コードの可読性を非常に高めてくれます。
Swiftでは、パーシャルレンジ(部分的な範囲)という考え方もあり、例えば下限だけを指定する PartialRangeFrom
や、上限だけを指定する PartialRangeThrough
などがあります。これを使うと無限に続く範囲を表現することができ、特定の値から無限大までの範囲を示せます。
演算子を適切に用いることによって、クローズドレンジなどの型を楽に選択できるのがSwiftの強みです。また、ジェネリクスを使って関数を定義すれば、異なる範囲でも一貫した処理を行うことができ、特定の値が範囲に含まれているかどうかを判定できるなど、柔軟な設計が可能になります。このように、構造を意識してコードを書くことで、Swiftの範囲を最大限に活用した効率的かつ可読性の高いプログラムを作成できます。
ただし、範囲を使用する際には矛盾した範囲を定義しないように注意する必要がありますし、無限ループなども避けるべきです。これらの点を意識しつつ、うまく範囲機能を活用していくと良いでしょう。 今日はここまでにしておきましょう。ジェネリクスの話は続きますが、時間になりましたので、終了といたします。お疲れ様でした。ありがとうございました。