列挙型 (enum)

ここでは Swift の enum、すなわち列挙型 (enumerated type) について説明します。 C 言語などを学んだことがあるひとは、enum というと整数に名前が付いたようなものだな、という風に理解しているかもしれません。

しかし、Swift の場合はここ説明するようにより柔軟に使えて便利です。例えば、メンバーに関連する値が割り当てられるなどできます。

それでは順番にみていきましょう。

enum の基本的な使い方

次の例では、MyColor という列挙型を定義しています。

enum MyColor {
	case Blue
	case White
	case LightBlue
}

enum のメンバーすべてに、わざわざ case をつけて定義するのは特徴的ですね。

enum 型の値は次のように割り当てられます。

var c = MyColor.Blue

あるいは、既に型が決まっている場合は、ドット . からはじめて、次のようにも書けます。

var c: MyColor
c = .Blue

次の例では、enum 型を受け取る関数を定義して、呼び出しています。 switch の使い方をみてください。

enum MyColor {
	case Blue
	case White
	case LightBlue
}

func checkColor(color: MyColor) {
	switch color {
	case .Blue:
		print( "*** Good! It's blue." )
	case .White:
		print( "*** Okay! It's white." )
	default:
		print( "***" )
	}
}

var c: MyColor
c = .Blue

checkColor(color: c)

この実行例は次のようになります。

*** Good! It's blue.

このように switch では場合分けをする case に enum 型のメンバーを指定できます。

enum での関連する値の割り当て

C 言語などでは enum は数値に名前を付けた程度のものですが、Swift ではもっと発展しています。 それぞれのメンバーに関連値 (associated value) を割り当てることができます。

正式の日本語訳が見当たらなかったので Associated value という言葉の訳として、ここでは「関連値」としました。 正式な資料に別の訳語が当てられていたらそちらを覚えてください。

次の例では PersonAttribute という enum 型を定義していますが、 Name メンバーには String 型の値が、 Age メンバーには Int 型の値が紐付けられるようにしてあります。

enum PersonAttribute {
	case Name(name: String)
	case Age(age: Int)
}

これをどうやって使うのでしょうか。関連値付きの enum 型のメンバーの割り当てに対して、 それぞれ値を設定できます。

var n = PersonAttribute.Name(name: "Nick")
var a = PersonAttribute.Age(age: 25)

この例では変数 n を宣言して、PersonAttributeName として、 さらにそれに関連した値として "Nick" という文字列をセットしています。

また変数 a を宣言して、PersonAttributeAge として、 さらにそれに関連した値として 25 という整数値 (Int) をセットしています。

さらに関連値は switch 文の case で評価できます。

func checkAttr(attr: PersonAttribute){
	switch attr {
	case .Name(name: "Nick"):
		print("My name is Nick.")
	case .Name:
		print("*** Other name ***")
		print(attr)
	default:
		print("*** Other attr ***")
		print(attr)
	}
}

var n = PersonAttribute.Name(name: "Nick")
var n2 = PersonAttribute.Name(name: "Mike")
var a = PersonAttribute.Age(age: 25)

checkAttr(attr:n)
checkAttr(attr:n2)
checkAttr(attr:a)

この実行結果は次の通りです。

My name is Nick.
*** Other name ***
Name("Mike")
*** Other attr ***
Age(25)

また case にて関連値を変数にセットすることもできます。

次の例では Name メンバーに関連付けされた文字列値を変数 name で受け取っています。

enum PersonAttribute {
	case Name(name: String)
	case Age(age: Int)
}

func checkAttr(attr:PersonAttribute){
	switch attr {
	case .Name(let name):
		print("My name is \(name).")
	default:
		print( "--- default ---")
		print(attr)
	}
}

var n = PersonAttribute.Name(name: "Nick")
var n2 = PersonAttribute.Name(name: "Mike")

checkAttr(attr:n)
checkAttr(attr:n2)

この結果は次のようになります。

My name is Nick.
My name is Mike.

また、数値の評価の例は次の通りです。最初の case では case .Age(age: 0...10): とすることにより、「Age メンバーに関連付けされた値が 0 から 10 の場合」という条件分けを設定しています。

enum PersonAttribute {
	case Name(name: String)
	case Age(age: Int)
}

func checkAttr(attr: PersonAttribute) {
    switch attr {
    case .Age(age: 0...10):
        print("Age = 0...10")
    case .Age:
        print("Age = Other")
    default:
        print(" *** ")
    }
}

var a1 = PersonAttribute.Age( age: 5 )
var a2 = PersonAttribute.Age( age: 20 )

checkAttr(attr: a1)
checkAttr(attr: a2)

実行結果は次の通り。

Age = 0...10
Age = Other

尚、case での条件判定は上から順に評価されて、最初に合致した条件の部分を通ることになります。したがって、 case での条件は上から順番に厳しい条件から緩い条件で記述します。

以上、ここでは Swift での列挙型の使い方に付いて説明しました。

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 Swift による iOS 開発入門