[Swift] enum の associated Value へのアクセス

Swift

定義された enum の associated value へのアクセス方法を説明します。

環境&対象

以下の環境で動作確認を行なっています。

  • macOS Big Sur 11.2.1
  • Xcode 12.4
  • Swift5.3.2

記事中のコードは、Playground で動作します。

enum

class, struct と並んで、3大主要構成要素 (first class) です。

ですが、あまり積極的に使われていない気がするので、少し凝った使い方を説明します。

enum 基本編

enum の定義

他の言語と同様に、特定の有限数の集合を表現できます。

以下は、Size と名付けた enum の定義です

enum Size

Size という型を使うことで、S,M,L の値のいずれかを持っていることを保証できます。

enum を使わないとすると Int 型を使用して定義し、1がSを表し、2、3がM,Lを表すという運用をすることになりますが、Size を表す型は Int 型であるために、4や5が設定されることを言語的には防止できません。

enum を使うことで、そのような制約を課すことができ、特定値の集合をもつような型を安全に使用することが可能となります。

enum への表現としての値の割り当て

C 言語等では、内部的に数値が割り振られて管理されますが、swift では、自動的には割り振られません。

明示的に数値を割り当てたい時には、以下のように定義します。

Size with Int,RawRepresentable

Int に準拠すると宣言したことで、整数を割り振ることを宣言し、RawRepresentable に準拠すると宣言したことで、
以下のように、rawValue プロパティでアクセスすることができるようになります。

example for Size with Int,RawRepresentable

上記のようにすることで、rawValue を +1 とすることで、サイズアップという操作にできます。(ただし、L の時にどうするかを検討しなければいけません)

この例のように enum の値が数値で表されることで、数値演算として処理できるようになり便利なることもあります。

Equatable

型として使うには、同値判定が必要となるケースがあります。

Equatable に準拠すると宣言するだけで、== で 同値判定を行うことができます。

enum Equatable example

ちなみに、RawRepresentable と宣言せずとも、Equatable に準拠させることができます。

enum Equatable example(2)

enum の associated value

Enum では特定値の集合を型として定義できるのですが、各値に対して、付加情報を追加することができます。associated value と呼ばれます。

associate value 付き enum の定義

以下は、Food という enum を定義し、種類(ピザ、ハンバーガー、おにぎり)を定義しています。associated value としてその量も保持できるようにしました。

example

ピザはサイズ情報をもち、ハンバーガーは数を、おにぎりはサイズと数の情報を associated value として持っています。

このように、enum に属する値がそれぞれ異なるタイプの associated value を持つことができます。

Equatable

associated value を定義していても、準拠するだけで、Equatable になります。

example

associated value へのアクセス(switch)

Associated value を指定するときは、コンストラクタで指定するためわかりやすいと思います。

associated value 指定のイニシャライザ 例

Associated value へのアクセスは、以下のようになります。

food を受け取り1人分の食事として多すぎないかをチェックする関数を以下のように定義しました。

checkTooMuch

上記のように switch 文で受け取る際に、 associated value を変数に受け取ることができます。

switch 文で enum を使って分岐するときには、全ケースを列挙するか default を指定しないとコンパイルエラーになります。

この仕様は思わぬエラーを防止するために、非常に便利なのですが、すでに どの enum であるかの前提があり、associated value を受け取りたいだけの時には、少し面倒です。

associated value は、次のような形でもアクセスすることができます。

associated value へのアクセス (条件節)

以下のように書くことで、すべてのケースを網羅することなく、特定の enum 値であることを確認してアクセスすることができます。

以下は、先の switch 文で記述した関数と同じ動作をする関数です。

checkTooMuch(if)

上記は、if 文で書いている例になっていますが、guard でも同様に使用することができます。

Swift おすすめ本

Swift を深く理解するには、以下の本がおすすめです。

説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です