使用if語句匹配枚舉的錯誤[duplicate]

[英]Error why matching an enumeration using a if statement [duplicate]


This question already has an answer here:

這個問題在這里已有答案:

I face a problem using enumeration I can't understand.

我使用枚舉我遇到一個問題,我無法理解。

Here is declaration of an enumeration type:

這是枚舉類型的聲明:

enum SomeType {
    case un
    case deux
    case trois
}

Then I want to match an individual enumeration values with a if statement:

然后我想將單個枚舉值與if語句匹配:

var testValue: SomeType = .trois

if testValue == .trois {
    // Do something
}

Everything is fine!

一切安好!

Now I want to add an associated value only to the first member value:

現在我想只為第一個成員值添加一個關聯值:

enum SomeType {
    case un(Int)
    case deux
    case trois
}

var testValue: SomeType = .trois

if testValue == .trois {
    // Do something
}

An error than appear on the if statement: Could not find member 'trois'

if語句中出現的錯誤:找不到成員'trois'

Does this mean enumerations can only be matched using a switchstatement?

這是否意味着只能使用switch語句匹配枚舉?

Precisions
What I want to achieve is: "Does testValue is of member value of 'trois' with no consideration for associated value". In others words, how to match an enumeration on member value only.

精確性我想要實現的是:“testValue是'trois'的成員價值而不考慮相關價值”。換句話說,如何僅在成員值上匹配枚舉。

Here a solution implementing Airspeed Velocity answers:

這里實現Airspeed Velocity的解決方案:

// Test equality only on member value
func == (lhs:SomeType, rhs:SomeType) -> Bool {
    switch (lhs, rhs) {
    case (.un(let lhsNum), .un(let rhsNum)):return true
    case (.deux, .deux): return true
    case (.trois, .trois): return true
    default: return false
    }
}

// Test equality on member value AND associated value
func === (lhs:SomeType, rhs:SomeType) -> Bool {
    switch (lhs, rhs) {
    case (.un(let lhsNum), .un(let rhsNum)) where lhsNum == rhsNum: return true
    case (.deux, .deux): return true
    case (.trois, .trois): return true
    default: return false
    }
}

var testValue = SomeType.un(3)


// Tests

if testValue == .un(1) {
    println("Same member value")
}


if testValue === .un(3) {
    println("Same member value AND same associated contents")
}

1 个解决方案

#1


9  

Enums that don't have associated types are automatically equatable. Enums that have associated types aren't. This makes sense, because only you can know how the associated type (such as the integer that comes with your .un value) should be handled. Even though .trois doesn't have an associated type, the lack of freebie equateableness affects the whole enum. Switch works a little differently, using pattern matching, so it still works.

沒有關聯類型的枚舉是自動等同的。具有關聯類型的枚舉不是。這是有道理的,因為只有你可以知道應該如何處理相關的類型(例如你的.un值附帶的整數)。即使.trois沒有相關類型,缺乏免費贈品等同性也會影響整個枚舉。使用模式匹配,Switch的工作方式略有不同,所以它仍然有效。

If you want your enum with an associated type to be equatable, you can define your own == operator:

如果您希望具有關聯類型的枚舉是等同的,則可以定義自己的==運算符:

enum SomeType {
    case un(Int)
    case deux
    case trois
}

// possibly there's a more succinct way to do this switch
func ==(lhs: SomeType, rhs: SomeType) -> Bool {
    switch (lhs,rhs) {
    case let (.un(i), .un(j)) where i == j: return true
    case (.deux,.deux): return true
    case (.trois, .trois): return true
    default: return false
    }
}

var testValue: SomeType = .trois

if testValue == .trois {
    println("equals .trois")
}

// note, for SomeType to work with generic
// functions that require Equatable, you have
// to add that too:
extension SomeType: Equatable { }

// which means this will work:
let a: [SomeType] = [.un(1), .deux, .trois]
find(a, .trois)

注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2014/12/18/73004c03018d5a69bab3a023afa258e9.html



 
粤ICP备14056181号  © 2014-2021 ITdaan.com