#book #wip [https://heart-of-swift.github.io/](https://heart-of-swift.github.io/) で公開されているオンラインブック # なぜこの本を読んだか iOSアプリケーションを作るにあたって Swift の protocol oriented な考え方をもうちょっと理解したかったから。 # 何が書かれている本か Value Semantics と Protocol-oriented Programming について様々な歴史的にも古い参考文献などに言及しながら説明している # メモ ## Value Semantics > For a type with value semantics, variable initialization, assignment, and argument-passing each create an independently modifiable copy of the source value that is interchangeable with the source. `ある型が Value Semantics を持つとき、その型の値が変更に対して独立である` というもの swift ``` struct Foo { var value: Int = 0 } var a = Foo() var b = a a.value = 2 // Foo は値型なので b は変更されないというのが Value Semantics を持っている状態 ``` その他の例 Immutable swift ``` final class Foo { let value: Int = 0 } var a = Foo() var b = a a.value = 2 // 代入がそもそもできない ``` Copy on write - Swift の Array は copy on write で値型を実現しているがこれも Value Semantics を持っていると言える - see also [“付録” > “Copy-on-Write”](https://heart-of-swift.github.io/appendix/copy-on-write) ## Protocol-oriented Programming 値型が設計の中心になっている Swift では、型の継承ができない e.g. swift ``` struct Cat: Animal { var value: UInt8 = 2 // 1 バイト func foo() -> Int { ... } } struct Dog: Animal { var value: Int32 = 1 // 4 バイト func foo() -> Int { ... } } // メモリの確保サイズ let cat: Cat = Cat() // 1 バイト let dog: Dog = Dog() // 4 バイト let animal: Animal = Bool.random() ? cat : dog // 40バイト!!!!! ``` Animal 型の変数が 40バイトも必要な理由はメモリの構造が非決定的であるからでこれを [Existential Container Layout](https://github.com/apple/swift/blob/master/docs/ABI/TypeLayout.rst#existential-container-layout) という仕組みで解決しているらしい。 Animal 型の大きさはサブタイプによって決定されるがそれ自体はいくらでも大きくできてしまう protocol らしい使い方は、 `パラメトリックポリモーフィズム` (パラメータ多相) である swift ``` // サブタイプポリモーフィズム func useAnimal(_ animal: Animal) { print(animal.foo()) } // パラメトリックポリモーフィズム // ジェネリクスを用いてコンパイルタイムに型自体の確定をする // 各個別の型 (上記の Cat や Dog) の実装をオーバーロードしたのと変わらないためインライン化されることもある func useAnimal<A: Animal>(_ animal: A) { print(animal.foo()) } ``` # 感想