Enumeration

構文

enum SomeEnumeration {
    // enumeration definition goes here
}

// 例
enum CompassPoint {
    case north
    case south
    case east
    case west
}

// 注意
// Cなどと異なり、デフォルトで整数値は設定されない。代わりに、明示的に定義されたCompassPoint型

// カンマで区切って、複数のケースを1行に表示できます。
enum Planet {
    case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune
}

// enum の名前は大文字で始め、単数形で表記すること

var directionToHead = CompassPoint.west
// directionToHeadの型は、CompassPoint型として推測できる
// したがって、値を設定するときに型を省略できます。
directionToHead = .east

Switchステートメントを使用した列挙値のマッチング

directionToHead = .south
switch directionToHead {
case .north:
    print("Lots of planets have a north")
case .south:
    print("Watch out for penguins")
case .east:
    print("Where the sun rises")
case .west:
    print("Where the skies are blue")
}
// Prints "Watch out for penguins"

enum caseの列挙

// CaseIterable 型を指定することにより、allCases で全てのケースを列挙できる
enum Beverage: CaseIterable {
    case coffee, tea, juice
}
let numberOfChoices = Beverage.allCases.count
print("\(numberOfChoices) beverages available")
// Prints "3 beverages available"

for beverage in Beverage.allCases {
    print(beverage)
}
// coffee
// tea
// juice

関連する値

UPCバーコードは4つの整数のタプル、QRコードバーコードを任意の長さの文字列として保存すると便利です。

// UPCバーコードとQRコードバーコードの両方を次のように表すことができる
enum Barcode {
    case upc(Int, Int, Int, Int)
    case qrCode(String)
}

var productBarcode = Barcode.upc(8, 85909, 51226, 3)
productBarcode = .qrCode("ABCDEFGHIJKLMNOP")

switch productBarcode {
case .upc(let numberSystem, let manufacturer, let product, let check):
    print("UPC: \(numberSystem), \(manufacturer), \(product), \(check).")
case .qrCode(let productCode):
    print("QR code: \(productCode).")
}
// Prints "QR code: ABCDEFGHIJKLMNOP."

Raw Value

// Raw Value の設定方法
enum ASCIIControlCharacter: Character {
    case tab = "\t"
    case lineFeed = "\n"
    case carriageReturn = "\r"
}

Raw Valueは、文字列、文字、または整数または浮動小数点型のいずれかで、enum 宣言内で一意である必要があります。

暗黙的に割り当てられた Raw Value

整数または文字列の未加工値を格納する列挙型を使用している場合、各ケースに未加工値を明示的に割り当てないと、自動的に値を割り当てます。

たとえば、生の値に整数が使用されている場合、各ケースの暗黙的な値は前のケースよりも1つ多くなります。最初のケースに値が設定されていない場合、その値は0です。

以下の列挙はPlanet、太陽からの各惑星の順序を表す整数の生の値を使用して、以前の列挙を改良したものです。

enum Planet: Int {
    case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
}
// この場合、Planet.venusは2が割り当てられます。

enum CompassPoint: String {
    case north, south, east, west
}
// この場合、CompassPoint.south は "south"が割り当てられます。

let earthsOrder = Planet.earth.rawValue
// earthsOrder is 3

let sunsetDirection = CompassPoint.west.rawValue
// sunsetDirection is "west"

Raw Value からの初期化

let possiblePlanet = Planet(rawValue: 7)
// possiblePlanet is of type Planet? and equals Planet.uranus
// すべての可能な値が一致する惑星を見つけるわけではありません。このため、Raw Value の初期化子は常にオプショナルの Enum型のケースを返します。

// 例えば、Raw Value が 11 の惑星は nil が返る
let positionToFind = 11
if let somePlanet = Planet(rawValue: positionToFind) {
    switch somePlanet {
    case .earth:
        print("Mostly harmless")
    default:
        print("Not a safe place for humans")
    }
} else {
    print("There isn't a planet at position \(positionToFind)")
}
// Prints "There isn't a planet at position 11"

再帰的 enum

indirectにより、再帰的な enum を表すことができる。

// 単純な算術式を表す再帰的 enum
enum ArithmeticExpression {
    case number(Int)
    indirect case addition(ArithmeticExpression, ArithmeticExpression)
    indirect case multiplication(ArithmeticExpression, ArithmeticExpression)
}

// すべてのケースに対して indirect enum を宣言することもできる
indirect enum ArithmeticExpression {
    case number(Int)
    case addition(ArithmeticExpression, ArithmeticExpression)
    case multiplication(ArithmeticExpression, ArithmeticExpression)
}

// (5 + 4) * 2 を再帰的 enum で表した例
let five = ArithmeticExpression.number(5)
let four = ArithmeticExpression.number(4)
let sum = ArithmeticExpression.addition(five, four)
let product = ArithmeticExpression.multiplication(sum, ArithmeticExpression.number(2))

// 評価する関数の例
func evaluate(_ expression: ArithmeticExpression) -> Int {
    switch expression {
    case let .number(value):
        return value
    case let .addition(left, right):
        return evaluate(left) + evaluate(right)
    case let .multiplication(left, right):
        return evaluate(left) * evaluate(right)
    }
}

print(evaluate(product))
// Prints "18"

この関数は、関連付けられた値を返すだけで、単純な数値を評価します。左側の式を評価し、右側の式を評価してから、それらを加算または乗算することにより、加算または乗算を評価します。

投稿者: admin

Free Software Engineer

コメントを残す

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