Swiftチュートリアルの列挙

6006 ワード

列挙
C言語では、C列挙は相関名を整数値のセットに割り当て、Swift列挙は列挙値ごとに値を指定する必要はありません.各列挙値に値(元の値と呼ばれる)が指定されている場合、この値は文字列、文字、または任意の整数または浮動小数点タイプの値であってもよい.
列挙は、他の言語の結合または変形と同様に、各列挙値とともに格納される任意のタイプの関連値を指定することもできます.
Swiftの列挙には、現在の列挙値の追加情報を提供するために属性を計算するなど、クラスによってのみ従来サポートされている多くの機能があり、列挙値に関連する機能を提供するためのインスタンスメソッドがあります.
列挙構文
Enumキーワードを使用して列挙を宣言します.
enum SomeEnumeration {
    // enumeration definition goes here
}

羅針盤の4つの方向の例を以下に示します.
enum CompassPoint {
    case north
    case south
    case east
    case west
}

caseキーワードを使用して新しい列挙状況を導入します.
に注意
CとObjective-Cとは異なり、Swiftの列挙値は作成時にデフォルトの整数値を割り当てません.上記列挙値は、0、1、2、3に暗黙的に等しくない.
複数のcaseは、カンマで区切られた1行に書くことができます.
enum Planet {
    case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune
}

各列挙は、他のタイプのように大文字で始まり、複数の名前ではなく単数です.
var directionToHead = CompassPoint.west

列挙タイプを使用してある列挙値を初期化すると、Swiftはその具体的な列挙タイプを推定し、次に値を再割り当てする場合、列挙タイプは無視できます.ポイント構文を使用するには:
directionToHead = .east

Switch文を使用して列挙値を一致させる
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"

switch文には、列挙値がないすべての値が含まれている必要があります.そうしないと、コンパイルできません.列挙が予期せぬ省略されないことを確認します.
defaultを使用して、明確に処理されていない列挙値をカバーします.
let somePlanet = Planet.earth
switch somePlanet {
case .earth:
    print("Mostly harmless")
default:
    print("Not a safe place for humans")
}
// Prints "Mostly harmless"

関連値
他のタイプの値と列挙値を関連付けて列挙値とともに格納し、その情報を使用するたびに変化する場合があります.
次に、関連する値を持つバーコードの列挙を示します.
enum Barcode {
    case upc(Int, Int, Int, Int)
    case qrCode(String)
}

関連値には、タイプの実際の値は指定されず、列挙値に格納された関連値のタイプのみが指定されます.
いずれかのタイプを使用して列挙値を作成します.
var productBarcode = Barcode.upc(8, 85909, 51226, 3)

productBarcode = .qrCode("ABCDEFGHIJKLMNOP")

switchを使用して関連値を抽出するには、次の手順に従います.
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."

相関値はすべて定数または変数として抽出されます.
switch productBarcode {
case let .upc(numberSystem, manufacturer, product, check):
    print("UPC : \(numberSystem), \(manufacturer), \(product), \(check).")
case let .qrCode(productCode):
    print("QR code: \(productCode).")
}
// Prints "QR code: ABCDEFGHIJKLMNOP."

元の値
列挙値は、タイプが一致するデフォルト値(すなわち、元の値)を使用して入力できます.
enum ASCIIControlCharacter: Character {
    case tab = "\t"
    case lineFeed = "
" case carriageReturn = "\r" }

元の値は、文字列、文字、または任意の整数または浮動小数点数タイプであり、各元の値は一意である必要があります.
暗黙的割当て列挙値
各列挙値に割り当て元の値を表示する必要はなく、Swiftは自動的に割り当てられます.
整数が元の値に使用されると、最初の列挙値は自動的に0に設定され、その後1が増加します.
enum Planet: Int {
    case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
}

上の例ではPlanet.Planetには明示的な元の値1があり、その他は暗黙的な列挙値に基づいて1を増やします.
文字列が元の値である場合、各列挙値の隠し元の値は、その列挙値の文字列字面量である.
enum CompassPoint: String {
    case north, south, east, west
}

上記の例では、CompassPoint.southの暗黙的な元の値は「south」です.
列挙タイプのrawValueプロパティを使用して、列挙値の元の値を取得します.
let earthsOrder = Planet.earth.rawValue
// earthsOrder is 3
 
let sunsetDirection = CompassPoint.west.rawValue
// sunsetDirection is "west"

列挙値を元の値で初期化
元の値タイプを使用して列挙を定義すると、列挙は自動的に初期化器を作成し、元の値の初期化器で列挙のインスタンスを作成できます.
let possiblePlanet = Planet(rawValue: 7)
// possiblePlanet is of type Planet? and equals Planet.uranus

しかしながら、すべての元の値が一致する列挙値を見つけることができるわけではないので、元の値初期化器(失敗可能な初期化器)は常に列挙のオプションタイプを返し、オプションバインディングとswitch文を組み合わせてオプションタイプを処理することができる.
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"

再帰列挙
列挙値の関連値タイプが列挙タイプである場合、列挙は再帰列挙である.
再帰列挙には2つの書き方があります.
  • 再帰が必要な列挙値の前にindirectキーワードを追加し、一部の列挙値に再帰を有効にします.

  • `
    enum ArithmeticExpression {
        case number(Int)
        indirect case addition(ArithmeticExpression, ArithmeticExpression)
        indirect case multiplication(ArithmeticExpression, ArithmeticExpression)
    }
    

    2.列挙タイプenumキーワードを宣言する前にindirectキーワードを追加し、すべての列挙値に再帰を有効にします.
    indirect enum ArithmeticExpression {
        case number(Int)
        case addition(ArithmeticExpression, ArithmeticExpression)
        case multiplication(ArithmeticExpression, ArithmeticExpression)
    }
    

    上記の再帰列挙例を作成します.
    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"