Swift Switch案例"不是"

时间:2015-08-02 15:53:45

标签: swift switch-statement

我有两个枚举:

public enum ServerState {
  case Connecting
  case Open
  case LoggedIn
  case Closed
  case Error(NSError)
}

enum TransportLayerState {
  case Disconnected(NSError?)
  case Connecting
  case Connected
}

我需要在它们之间切换,如果并且返回' false'如果ServerState设置为基础TL状态不可能的状态。例如,如果serverState == .Open && tlState == .Disconnected,它将返回false。我尝试使用switch语句尝试这样做,但我发现我真正想要的是匹配其中一个状态特定状态的情况。例如:

switch (serverState, tlState) {
case (.Connecting, !.Connecting): return false
case (.Closed, !.Disconnected(.None)): return false
case (.Error(_), !.Disconnected(.Some(_)): return false
case (.Open, !.Connected), (.LoggedIn, !.Connected): return false
default: return true
}

显然这不起作用,因为你不能在案例陈述之前放置!。我唯一的另一个选择是指定所有允许的情况,这些情况要多得多。指定限制并允许所有其他状态组合更有意义,但我不确定如何执行此操作。有任何想法吗?我也试图避免嵌套的switch语句。

注意:我知道我可以使用Swift 2' if case执行此操作,但我现在无法使用Swift 2,因为这是生产代码。所以请回答Swift 1.2中的解决方案。

2 个答案:

答案 0 :(得分:8)

由于所有模式都是按顺序检查的(并且第一次匹配“获胜”), 你可以做到以下几点:

switch (serverState, tlState) {

case (.Connecting, .Connecting): return true // Both connecting 
case (.Connecting, _): return false  // First connecting, second something else

case (.Closed, .Disconnected(.None)): return true
case (.Closed, _): return false

// and so on ...

所以一般情况下,匹配其中一个状态特定状态的情况可以用两种模式完成:第一个匹配状态, 第二个是通配符模式(_),然后匹配所有其他模式 例。

答案 1 :(得分:1)

我发现一个可能的答案是使TransportLayerState等于。在那种情况下,我可以这样做:

switch serverState {
case .Connecting where tlState != .Connecting: return false
case .Closed where tlState != .Disconnected(nil): return false
case let .Error(err) where tlState != .Diconnected(err): return false
...
default: return true
}

我最终不得不在TransportLayerState枚举中编写一些代码以使其等同,所以不确定它是否值得付出努力,但确实有效。