我可以将枚举限制为另一个枚举的某些情况吗?

Mis*_*cha 9 enums restriction swift

说我有面包店和成分库存:

enum Ingredient {
    case flower     = 1
    case sugar      = 2
    case yeast      = 3
    case eggs       = 4
    case milk       = 5
    case almonds    = 6
    case chocolate  = 7
    case salt       = 8
}
Run Code Online (Sandbox Code Playgroud)

案例rawValue代表库存编号.

然后我有两个食谱:

巧克力蛋糕:

  • 500克花
  • 300克糖
  • 3个鸡蛋
  • 200毫升牛奶
  • 200克巧克力

杏仁蛋糕:

  • 300克花
  • 200克糖
  • 20克酵母
  • 200克杏仁
  • 5个鸡蛋
  • 2克盐

现在我定义一个函数

func bake(with ingredients: [Ingredient]) -> Cake
Run Code Online (Sandbox Code Playgroud)

当然,我相信我的员工,但我仍然想确保他们只使用正确的成分来烘焙蛋糕.

我可以通过定义两个单独的枚举来做到这一点:

enum ChocolateCakeIngredient {
    case flower
    case sugar
    case eggs
    case milk
    case chocolate
}

enum AlmondCakeIngredient {
    case flower
    case sugar
    case yeast
    case eggs
    case almonds
    case salt
}
Run Code Online (Sandbox Code Playgroud)

并烤一个像这样的蛋糕:

// in chocolate cake class / struct:
func bake(with ingredients: [ChocolateCakeIngredient]) -> ChocolateCake
// in almond cake class / struct:
func bake(with ingredients: [AlmondCakeIngredient]) -> AlmondCake
Run Code Online (Sandbox Code Playgroud)

但随后我不得不一遍又一遍地重新定义相同的成分,因为两种蛋糕都使用了许多成分.我真的不想这样做 - 特别是因为枚举案例中附有库存编号rawValue.

这引出了一个问题,即Swift中是否有一种方法可以将枚举限制为另一个枚举的某些情况?像(伪代码)的东西:

enum ChocolateCakeIngredient: Ingredient {
    allowedCases:
        case flower
        case sugar
        case eggs
        case milk
        case chocolate
}

enum AlmondCakeIngredient: Ingredient {
    allowedCases:
        case flower
        case sugar
        case yeast
        case eggs
        case almonds
        case salt
}
Run Code Online (Sandbox Code Playgroud)

这样的组合可能吗?我该怎么做?

或者也许我可以在这种情况下使用另一种模式?


更新

从这个问题的所有评论和答案中,我认为我为这个问题选择的例子有点不合适,因为它没有归结出问题的本质,并留下了关于类型安全的漏洞.

由于此页面上的所有帖子都与此特定示例相关,因此我在Stackoverflow上创建了一个新问题,其中包含一个更易于理解并触及其主题的示例:

➡️ 与更具体的例子相同的问题

sda*_*das 2

我认为你应该列出特定食谱的成分:

let chocolateCakeIngredients: [Ingredient] = [.flower, ...]
Run Code Online (Sandbox Code Playgroud)

然后检查该列表是否包含所需的成分。

  • 这可能会更好地实现为“Set”,用于恒定时间查找。 (2认同)