Swift Switch Case Not

I have two enumerations:

public enum ServerState { case Connecting case Open case LoggedIn case Closed case Error(NSError) } enum TransportLayerState { case Disconnected(NSError?) case Connecting case Connected } 

I need to switch between them if I return "false" if ServerState is set to a state that is not possible in the base state of TL. For example, it will return false if serverState == .Open && tlState == .Disconnected . I try to do this using the switch statement, but I believe that I really want to match the case where one of the states is not a specific state. For instance:

 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 } 

Obviously this does not work because you cannot fit ! before the case statement. My only option is to indicate all valid cases that are much more numerous. It makes sense to specify restrictions and allow all other combinations of states, but I'm not sure how to do this. Any ideas? I am also trying to avoid nested switch statements.

Note. I know that I can do this with Swift 2 if case , but right now I cannot use Swift 2, as this is production code. So please answer the solutions in Swift 1.2.

+3
source share
2 answers

Since all patterns are checked sequentially (and the first match wins), you can do the following:

 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 ... 

So, in the general case, the coincidence of the case when one of the states is not a specific state can be performed with two patterns: the first corresponds to the state, and the second corresponds to the substitution pattern ( _ ), which then corresponds to all other cases.

+8
source

One of the possible answers I found was to make TransportLayerState equivalent. In this case, I could do this:

 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 } 

I need to write some code in the TransportLayerState enum to make it equivalent, so I'm not sure if it's worth it, but it works.

+1
source

Source: https://habr.com/ru/post/1261416/


All Articles