2017-07-14 62 views
1

我有這樣的結構有一個枚舉屬性,以及一個功能:斯威夫特3枚舉與相關的價值和功能比較

struct UserInput { 
    enum State { 
    case unrestricted 
    case restricted(because: WarningType) 

    enum WarningType { 
     case offline 
     case forbidden 
    } 
    } 

    var config: UserInputConfig? 
    var state: State = .unrestricted 

    func isConfigured() -> Bool { 
    // Arbitrary checks about the config... 
    } 
} 

有沒有辦法改寫以下條件語句,以便檢查isConfigured()state是在相同的聲明?

if case .restricted = userInput.state { 
    return 1 
} else if userInput.isConfigured() { 
    return 1 
} else { 
    return 0 
} 

這似乎是因爲State枚舉使用相關的值,你不能簡單地寫if userInput.state == .restricted || userInput.isConfigured(),您需要使用if case語法。必須有解決辦法嗎?

+0

我在我的答案中添加了一個*多分條件*方法,它更短,更易讀,並且短路。 – vacawama

回答

2

你想做到這一點:

if case .restricted = userInput.state || userInput.isConfigured() { 
    return 1 
} else { 
    return 0 
} 

,但目前還沒有辦法做到的OR模式匹配。有幾種方法可以做

使用DeMorgan's Laws,你可以把if a || bif !(!a && !b),並通過反轉然後其他條款您if語句,你可以檢查if !a && !b

不幸的是,你不能說if !(case .restricted = userInput.state),但由於你的枚舉只有2個情況,你可以用if case .unrestricted = userInput.state替換它。

現在,你如何使用它與另一種說法?由於您不能使用||的原因,您不能使用&&

您可以通過使用這兩個失敗的條件相匹配的模式(這是使用),然後返回1如果兩個失敗的條件都不滿足檢查失敗的情況下:

if case (.unrestricted, false) = (userInput.state, userInput.isConfigured()) { 
    return 0 
} else { 
    return 1 
} 

等效你可以使用一個多子句的條件

if case .unrestricted = userInput.state, !userInput.isConfigured() { 
    return 0 
} else { 
    return 1 
} 

除了較短和IMO更易於閱讀外,第二種方法可以在短路以及在case .unrestricted = userInput.state出現故障的情況下跳過呼叫userInput.isConfigured

+0

雖然這不是'||',但它本質上是'&&'的作用? – Elise

+2

這是正確的。我基本上用!(!a &&!b)代替(a || b),它根據德摩根定律是等價的。 – vacawama

1

您可以用switch聲明這樣做真乾淨,和模式匹配:

switch userInput.state 
{ 
    case .unrestricted: 
     return userInput.isConfigured() ? 1 : 0; 

    case .restricted(_): 
     return 1 
}