在Swift中使用带有相关值的枚举是否违反Liskov替换原则?

时间:2016-10-09 12:36:02

标签: swift enums solid-principles liskov-substitution-principle

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

我刚刚在Swift教程中看到了这一点,我无法相信他们允许你这样做。现在,每当我打开枚举时,我都要为cloudy创建一个特殊情况!

3 个答案:

答案 0 :(得分:3)

你没有"得到"做任何事情。如果您不在乎保险范围,请不要问保险范围是什么。如果你不关心它是否是阴天,不要问它是否是阴天。关于为具有关联值的案例编写开关的方式, nothing 是特别的。

假设我们有这个:

let weather = WeatherType.cloudy(coverage:1)

然后这是完全合法的:

switch weather {
case .sunny:
    print("it is sunny")
default:
    print("I guess it's cloudy, or maybe windy")
}

这就是这个!

switch weather {
case .cloudy:
    print("it is cloudy")
default:
    print("I guess it's sunny, or maybe windy")
}

任何法律都没有要求你写一个switch语句。如果您只是想知道weather.cloudy,请问:

if case .cloudy = weather {
    print("yes it is cloudy")
} else {
    print("I guess it's sunny, or maybe windy")
}

如果你碰巧想知道coverage是什么,你仍然不必写一个switch语句:< / p>

if case let .cloudy(cov) = weather {
    print("yes it is cloudy, in fact it is \(cov)")
} else {
    print("I guess it's sunny, or maybe windy")
}

无法做的是申请==。这不会编译:

if weather == .sunny { // error

在某种程度上,是的,具有关联值的枚举与没有关联值的枚举的行为不同(如果这是您要求的)。

答案 1 :(得分:2)

  

现在,每当我打开enum时,我都要为cloudy创建一个特殊情况!

这不是真的,原因如下:

  • 您可以忽略cloudy,将其与default
  • 捆绑在一起
  • 模式匹配可让您阅读coverage的{​​{1}}属性,同时将cloudy本身视为单个案例。
  • 当您阅读属性cloudy时,您可以选择忽略它,或对其采取行动。

以下是一些例子:

coverage

答案 2 :(得分:2)

Liskov Substitution Principle与子类化有关。枚举不允许子类化,因此不适用于此。

我不确定您为cloudy创建特殊案例的异议是什么;如果你想专门处理这种情况,你必须在switch中做到这一点。获取相关值的额外语法非常简单。

let weather = WeatherType.cloudy(coverage: 17)

switch weather {
case .sunny:
    print("sunny")
case .windy:
    print("windy")
case .cloudy(let coverage):
    print("cloudy with coverage \(coverage)")
}