2015-11-06 22 views
1
class MyClass 
{ 
    enum MyEnum { 
     case FirstCase 
     case SecondCase(Int) 
     case ThirdCase 
    } 

    var state:MyEnum! 

    func myMethod() 
    { 
     if state! == MyEnum.FirstCase { 
      // Do something 
     } 
    } 
} 

我得到的編譯器錯誤在if聲明::將枚舉類型的值與關聯值進行比較時發生編譯器錯誤?

二元運算符 '==' 不能適用於兩個 'MyClass.MyEnum' 操作數

如果不是指向,我用switch聲明,沒有問題:

switch state! { 
    // Also, why do I need `!` if state is already an 
    // implicitly unwrapped optional? Is it because optionals also 
    // are internally enums, and the compiler gets confused? 

case .FirstCase: 
    // do something... 

default: 
    // (do nothing) 
    break 
} 

但是, switch聲明感覺過於冗長:我只是想爲.FirstCase,沒有其他的東西。一個if聲明更有意義。

怎麼回事enums和==

編輯:這是非常奇怪的。在解決了switch版本並轉到我的代碼的其他(完全不相關)部分並返回之後,if-聲明版本(針對固定枚舉大小寫的解壓縮屬性)正在編譯時沒有錯誤。 我只能得出結論,它與解析器中一些被破壞的緩存有關。

EDIT 2(感謝@LeoDabus和@MartinR):看來,當我相關的值設置爲其他枚舉的情況下(不是一個我比較反對出現錯誤 - 在這種情況下,。 SecondCase)。我仍然不明白爲什麼會特別觸發這個編譯器錯誤(「不能使用二元運算符=='...」),或者這意味着什麼。

+0

您忘記了初始化狀態,並且正在強制解包它。 add guard let state = else else {return} –

+0

這是虛擬代碼,類型和變量名稱已更改,大多數方法都被省略。在我的真實代碼中,var **被初始化。無論是哪種情況,最多都應該是運行時問題。實際上,我正在測試'viewDidLoad()'中的值,編譯器無法知道它是否被初始化。 –

+0

您使用的是什麼Xcode版本?我在這裏沒有得到這個錯誤 –

回答

4

正如您在評論中所說的,您的枚舉類型實際上具有關聯的 值。在這種情況下,枚舉類型沒有默認的==運算符。

但是你可以使用模式在if聲明甚至匹配(因爲斯威夫特2):

class MyClass { 
    enum MyEnum { 
     case FirstCase 
     case SecondCase 
     case ThirdCase(Int) 
    } 

    var state:MyEnum! 

    func myMethod() { 
     if case .FirstCase? = state { 

     } 
    } 
} 

這裏.FirstCase?.Some(MyEnum.FirstCase)一個快捷方式。

在您的switch語句,state不會自動解開, 哪怕是一個隱含展開可選的(否則你 不匹配對nil)。但是可以使用相同的模式:

switch state { 
case .FirstCase?: 
    // do something... 
default: 
    break 
} 
+0

非常感謝。我最終不需要我當前代碼中的相關值,所以'if'語句按照最初的計劃工作,但會記住這個模式以供將來參考。 –

+0

@Martin R:可選(E.A)== E.A //在Swift 2中爲我提供了真實 – user3441734

+0

@ user3441734:對不起,我不明白你在問什麼。 –

1
class MyClass { 
    enum MyEnum { 
     case FirstCase 
     case SecondCase 
     case ThirdCase 
    } 

    var state: MyEnum! 

    func myMethod() { 
     guard 
      let state = state else { return } 

     if state == MyEnum.FirstCase { 
      // Do something 
      print(true) 
     } else { 
      print(false) 
     } 
    } 
} 


let myClass = MyClass() 
myClass.state = .FirstCase 
myClass.myMethod() 
myClass.state = .SecondCase 
myClass.myMethod() 
+0

如果不是首先使用'guard'展開,會跳過它,只是試圖比較'state! == MyEnum.FirstCase'? –

+0

@NicolasMiari只要你初始化狀態屬性 –

+0

你的代碼在這裏運行良好我再說一遍:編譯器(靜態分析器?)有**無法知道**如果屬性被初始化或不在它使用的位置( 'viewDidLoad'),並且我強制展開它(我不需要這樣做,因爲它開始時是一個隱含的unwrapped可選項)。編譯器錯誤我得到了與初始化無關,但比較相同類型的兩個枚舉**(?????) –