Swiftにあるもう一つの型分類
新規プロジェクトをSwiftで、ということになったのでSwiftを勉強していると、伝統的なプログラミング言語ではあまり見かけない型分類があるのに気付いた。そしてこれを正しく理解することがSwiftで「成功」するための必要条件のようなのである。
それが参照型、値型という分類だ。これはInt型、String型という時の「型」とは趣きが違っていて、あるオブジェクトをどのように扱うべきかが事前に決まっていると言うものだ。
classは参照型structは値型
C++ではオブジェクトを関数の引数として渡すときに参照で渡したり、値で渡したりすることをよくやる。しかしこのようにオブジェクトの種類と完全にくっつけられた「型」ではなかった。
classとclosureは参照型(Reference Types)
struct, enumは値型(Value Types)
と決まっている。closureやenumはそれぞれ独自の性質を持っているので使用に際して迷うところはないと思える。問題は機能が似ているClassとStructureだ。
多くの性質は共通するものの一部性質が異なる。
参照型のClassと値型のStructureで共通する性質
以下の性質はどちらにもある。
- プロパティ
定数や変数のプロパティを持てる。 - メソッド
様々なメソッドを実装できる - 初期化のメカニズム
何らかの形で初期化して利用できる。init()のようなある種のメソッド(Initializer)を用意することができる。 - アクセス手段
内部の変数にアクセスする手段(abc.xなど)がある。 - Extend
Plotocolを用いてExtendできる。余談だがSwiftはPlotocol Oriented Programming (POP)を実現した最初のプログラミング言語らしい。POPの利用が推奨されているようだ。POPについてはまた改めて書こうと思う。
参照型のClassのみの性質
- 継承が使える
UIなど継承を使わざるを得ない場合は一択になる。 - オブジェクトはHeapに置かれる
比較的潤沢なメモリを使えるが、遅いのが弱点。
値型のStructureのみの性質
- 継承は使えない
継承を利用した方が多大なコスト削減ができるならデメリットになる。 - オブジェクトはStackに置かれる
Heapより量的には少ないが高速動作が見込める。
まとめ:どんな時にどちらを用いればよいのか
アップルの開発者ドキュメントに書かれているが、UIなど継承が不可欠な場合を除き、まず値型のstructで実装してみる。
あまりに継承を利用できないデメリットが大きければclassの利用を検討する。
というのが基本姿勢だと思う。実際、AppleのリファレンスでNSなんとかを調べているとSwiftではstructを推奨すると出ている。
最近、NSDate classを調べたらDate structの利用を強く勧められた。
実際、ClassからStructureは難しいが、StructureからClassへの変更は比較的容易な事もある。
Swiftも奥が深い。