渡部渡部
  • このエントリーをはてなブックマークに追加
  • Pocket   

Swiftでの列挙型(enum)の気持ちを、クラスと構造体から考えてみた。

swift_0327

こんにちは、すいふぁー渡部です。

 

以前の「Swift入門者が覚えておきたい17項目」の列挙型でも書きましたが、Swiftの列挙型(enum)って凄い色々出来るんですよね。関数を記述できるし、値持ってるし。

 

で、ふと気がついた。

 

これってクラスとか構造体と同じようなクラス・型を定義するものなんじゃないかと。

 

という訳で、Swiftの列挙型をクラス、構造体と比較してみることで、新しい型を作る定義なのか、どうかを考えてみたいと思います。

 

検証環境は、Xcode6.2で行っています。

 

列挙型はクラスの夢を見るか?

全く関係ないですが、ブレードランナーの続編が2015年、今年の夏から作成が開始されるらしいですね。っと、楽しみにしていましたが、記事を書いてる最中に、出演を予定していたハリソン・フォード氏が事故ったそうで、どうなるんですかね。

 

それでは、今回の主役たちをご紹介したいと思います。

 

今回出場する3人を定義する。

1.クラス

クラスの定義はこう!

 

今回は「TestClass」という名前で定義した。

 

2.構造体

構造体の定義はこれ!

 

今回は「TestStruct」という名前で定義する。

 

3.列挙型

列挙型の定義!

 

今回は主役を「TestEnum」という名前で定義します。

 

変数・定数・メソッドを定義してみる。

1.クラス

まぁ当たり前ですが、普通に定義可能です。

 

2.構造体

これも当然ですが、定義可能です。

 

3.列挙型

varやletの定義は出来ません(Xcode上でエラーになる)が、caseで定数定義、変数はcaseで定義されたいずれかの1つの値になりますが、定義できてると思います。

 

更に検証

Swift入門者が覚えておきたい17項目」の構造体でも書いた、クラスと構造体を分ける4つの要素で検証してみる。

 

1.継承

1.クラス

普通に大丈夫。

 

2.構造体

構造体は継承が出来ない事になっているが、継承できないとはどういうことなのかを確認してみた。

 

継承は出来ない。

 

プロトコルの継承は出来る。

 

クラスから継承は出来ない。

 

クラスへの継承も出来ない。

つまり構造体の継承が出来ないとは、プロトコルの成約を受ける構造体は作成可能だが、構造体を基底クラスや、派生クラスにすることは出来ないという事のようです。

 

3.列挙型

列挙型からの継承は出来ない。

 

リテラルな型からの継承?は可能。(記述的には継承っぽいけど、これを継承と呼ぶのか・・?)

 

クラスからの継承?も可能。(ちょっと強引だけど)

 

構造体からの継承も可能。

 

因みに、以下のいずれかのプロトコルとEquatableを継承することで、enumで使用することが出来ます。

整数値 : IntegerLiteralConvertible

浮動小数点 : FloatingPointLiteralConvertible

文字列 : StringLiteralConvertible

真偽値 : BooleanLiteralConvertible

 

プロトコルの継承は可能

 

ここまで見た感じだと列挙型の定義は、プロトコルやリテラルな型を継承可能であり、構造体に近い定義のようです。

 

2.終了処理(deinit)が出来ない。

クラスは当然定義可能

 

構造体は当然エラーになる。

 

列挙型は・・・・?

初期化は出来るが、終了処理は出来ない。構造体に似た動きをする事がわかる。

 

3.構造体で定義した値は値渡しになり、クラスで定義した値は参照渡しになる。

クラスは参照渡しになる。

 

構造体は、書き換える記述時にエラーになる。ただし、inoutを使用すれば、値の書き換えは可能。

 

列挙型は、内部に書き換える構造が見つからないので、検証不可能…(出来る方法あるなら教えてください)

ということは、初期値で与えられた値以外の値は持てないと言うことだと思います。

 

4.型のキャストが出来ない

クラスは、継承関係があるから当然出来る。

 

構造体はそもそも継承が出来ないので、キャストが出来ないが、プロトコルへのキャスト可能。

 

列挙型は、直接キャストは出来ないが、rawValueで継承元の値に変換可能。

ここまで見てくると、当初考えていた列挙型は新しい型を作ると言うよりは、構造体の仕組みを利用した既存のリテラルの拡張表現の様な気がしてきました。

 

 

その他機能

 

列挙型に値を持たせる事が可能ですと、書くと何のことかわかりにくいと思いますでの、例を紹介します。

と、ジェネリック型の様な使い方出来ます。

 

まとめ

最後まで読んで頂き、ありがとうございました。

 

僕の結論としては、

 

Swiftにおける列挙型は、リテラル型を拡張し、初期値で与えられた一意な値を持つものにするための宣言である。

 

皆さんはどう思いました?

 

Swiftの列挙型は結構色んな事が出来るので、色々やりたくなりますが、やり過ぎるとソースの可読性が一気に下がりそうです。少なくても直感的には理解出来ないと思います。

 

仕事でプログラミングする場合は、可読性も大切な要素のうちの1つなので、コーディング規約でこの辺をしっかり定義しないと、チームとしてのパフォーマンスが下がると思います。

 

Swift 言語は、言語的には綺麗じゃないけど、おもしろいですね。

 

 

【Swiftに関連する記事】

SwiftでECSlidingViewControllerを使ったドロワーメニューを実装してみた。

 

UITableView のセルに配置された UIDatePicker の表示・非表示切り替えを行う。〜 Swiftの話 〜

 

Swift入門者が覚えておきたい17項目

 

Swift超入門

 

SwiftでStoryboardを使った簡単な画面遷移(メモ的なもの)

 

 


  • このエントリーをはてなブックマークに追加
  • Pocket