CHAPTER 07 演算子

Swift に用意されている演算子とその優先順序、そして最近の言語にはよくある演算子を自分で定義できるという話。 実装方法はどうせまたその時に調べると思うので要点だけ書く。

  • 二項演算子は infix operator で定義する
  • 前置演算子は prefix operator で定義する
  • 後置演算子は postfix operator で定義する
  • それぞれ演算子の優先度を precedence で定義する
  • それぞれ演算子の結合規則を associativity で定義する

パターンマッチ演算子

Swift にはパターンマッチ演算子 ~= が用意されておりこれをオーバーライドすることで switch 文のパターンマッチの挙動を上書くことができる。 しかしこれはグローバルに定義されてしまうので対象を特定の列挙型に限定するなどの工夫が必要となる。

短絡評価をする演算子の定義

例えば三項演算子 a ? b : c みたいなものを自分で定義したい時に普通に書くと a を満たさなくても c が評価されてしまうのがまずい場合がある。 処理に時間が掛かる場合やログ出力を行う場合などだ。 こういう時は @autoclosure を使う:

// cond を満たさない時のみ処理を行う
func skip(cond: Bool, @autoclosure _ arg: () -> Int) {
    if !cond {
        print("value=\(arg())")
    }
}

CHAPTER 08 クラスと継承

クラスの概要

Java のクラスの知識がそのまま使えそうな雰囲気。構造体と違って mutating 修飾子は必要ない。

動的結合とキャスト

インスタンスの型が対象のものかをチェックする演算子は is でキャスト演算子は as, as!, as? である。 これは Kotlin と同様。

クラスメソッドとクラスプロパティ

なんか Python みたいだがタイプメソッドとタイププロパティ (static で記述するもの) の他にクラスメソッドとクラスプロパティ (class で記述するもの) がある。 class の方はサブクラスでオーバーライドできるが static のほうはできない。

指定イニシャライザと簡易イニシャライザ

Swift ではイニシャライザ (コンストラクタ) は init で定義するが init の中から他の init を呼ぶようなのを簡易イニシャライザ (他のイニシャライザの助けを借りるイニシャライザ) と良い convenience init で定義する。

必須イニシャライザ

required init で記述すると必須イニシャライザとなり継承先のクラスでも同一のイニシャライザを必ず実装しなければならなくなる。

遅延格納型プロパティ

Kotlin と一緒で lazy で指定すると遅延格納型となる。

CHAPTER 09 メモリ管理

この辺りは難しい話なので、読み物として読んでおくだけでいいのではと思う。

弱い参照

Java でいうところの WeakReference (弱参照) を実現するのに weak キーワードを使用する。

CHAPTER 10 プロトコル

要するに Java のインターフェース。

オプション項目のあるプロトコルを宣言する

必ずしも実装する必要のないメソッドやプロパティを宣言することができる。optional を先頭につければよい。

ネスト型とプロトコル

Java でいうところのジェネリクス (型パラメータ) は typealias キーワードで定義する。

CHAPTER 11 拡張

Kotlin と同様にすでにあるクラスに対し機能を追加することができる。 これをエクステンションと呼ぶ。