0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[Swift] 値付き enum は CaseIterable をつけても allCases を自身で定義しなければならない件

0
Posted at

この記事で分かること

  • 値付き enum で CaseIterable のプロトコルを適応させる場合、allCases を自身で定義しなければならない

具体例

例その1: CaseIterableの通常の使い方

enum Color: CaseIterable {
    case red, green, blue
}

Color.allCases.forEach {
    print($0)
}

// 出力
//
// red
// green
// blue

例その2: 値付きenumでCaseIterableを使う場合

以下のような値付き enum では CaseIterable とつけても Type 'Trade' does not conform to protocol 'CaseIterable' と怒られてしまいます。

enum Trade: CaseIterable { // Type 'Trade' does not conform to protocol 'CaseIterable'
    case buy(stock: String, amount: Int)
    case sell(stock: String, amount: Int)
}

そのため、以下のように allCases を自分で定義して、具体値を定義しなければなりません。

enum Trade: CaseIterable {
    // allCases を自分で定義しなければなない
    static var allCases: [Trade] {
        return [
            .buy(stock: "", amount: 0),
            .sell(stock: "", amount: 0)
        ]
    }
    
    case buy(stock: String, amount: Int)
    case sell(stock: String, amount: Int)
}

Trade.allCases.forEach {
    print($0)
}

// 出力
//
// buy(stock: "", amount: 0)
// sell(stock: "", amount: 0)

例その3: 値付きenumの「値」にenumを用いた場合

では、値付き enum の「値」を CaseIterable に適応した enum を用いた場合、どうなるのでしょうか?
「いい感じに察してくれないかな〜」と期待したいところですよね。

実際に試したところ、これもコンパイラに怒られてしまい、allCases を自分で定義しなければいけませんでした(泣)

無理やり書いてみると以下のようになりました。残念!!

enum FinancialProduct: CaseIterable {
    case stock
    case gold
    case crypto
}

enum Trade: CaseIterable {
    static var allCases: [Trade] {
        return [
            FinancialProduct.allCases.map { .buy(financialProduct: $0) },
            FinancialProduct.allCases.map { .sell(financialProduct: $0) },
        ].flatMap { $0 }
    }
        
    case buy(financialProduct: FinancialProduct)
    case sell(financialProduct: FinancialProduct)
}

Trade.allCases.forEach { trade -> () in
    switch trade {
    case let .buy(financialProduct):
        print("buy: \(financialProduct)")
    case let .sell(financialProduct):
        print("sell: \(financialProduct)")
    }
}

// 出力
//
// buy: stock
// buy: gold
// buy: crypto
// sell: stock
// sell: gold
// sell: crypto

結論

  • 値付き enumCaseIterable を使うのは注意が必要
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?