是否可以在枚举关联值条件和另一个枚举案例之间编写复合转换案例?

时间:2019-06-06 17:06:55

标签: swift enums

出于演示目的,我创建了下一个代码:

enum WeatherType {
    case cloudy(coverage: Int)
    case sunny
    case rainy
}

let today: WeatherType = .cloudy(coverage: 0)

switch today {
case .cloudy(let coverage) where coverage == 0, .sunny:   // <-- This line doesn't compile
    print("☀️")
case .cloudy(let coverage) where 1...100 ~= coverage:
    print("☁️")
case .rainy:
    print("?")
default:
    print("Unknown weather")
}

编译错误消息为'coverage' must be bound in every pattern。正如我已经在Google上搜索的那样,关联值的一种处理方式是在同一个枚举条件下比较值的不同状态。但这可能会导致代码重复,例如在我的示例中,我需要为.sunny.cloudy(let coverage) where coverage == 0编写两个case语句。

是否有任何正确,迅速的方式来处理此类案件?

3 个答案:

答案 0 :(得分:4)

您不需要匹配.cloudy(coverage: 0)的条件子句,只需

case .cloudy(coverage: 0), .sunny: 
    print("☀️")

例如,另一种选择是使用fallthrough

case .cloudy(let coverage) where coverage < 10:
    fallthrough
case .sunny:
    print("☀️")

答案 1 :(得分:3)

马丁是对的(+1)。

但是我可能建议您进一步完善,将您的switch移至WeatherType的扩展名(我可能会简称为Weather),这样您就不必每当您寻找符号时,请重复以下switch语句:

enum Weather {
    case cloudy(Int)
    case sunny
    case rainy
}

extension Weather {
    var symbol: String {
        switch self {
        case .cloudy(0), .sunny:
            return "☀️"
        case .cloudy:
            return "☁️"
        case .rainy:
            return "?"
        }
    }
}

然后您可以做:

let today: Weather = .cloudy(0)
print(today.symbol)

即使您想将少于10的东西都视为晴天,您仍然不需要where子句:

extension Weather {
    var symbol: String {
        switch self {
        case .cloudy(..<10), .sunny:
            return "☀️"
        case .cloudy:
            return "☁️"
        case .rainy:
            return "?"
        }
    }
}

答案 2 :(得分:2)

模式匹配是可组合的,因此您可以执行以下操作:

switch today {
case .sunny, .cloudy(0):
    print("☀️")
case .cloudy(1...10):
    print("☁️")
case .rainy:
    print("?")
default:
    print("Unknown weather")
}