簡體   English   中英

swift中的枚舉類

[英]Enum class in swift

我試圖創建一個具有類型和返回所有類型的函數的枚舉類。

最初,我的對象類中有我的枚舉和一個將這些作為數組返回的函數:

class someClass: Mappable {

enum Type: Int {
    case A = 0
    case B = 1
    case C = 2
        }
    }
}

func getAllTypes() -> [Type] {
    return [Type.A, Type.B, Type.C]
}
}

我想從我的對象類中提取它的原因是因為這個類型也在其他類中使用,我不想復制任何不必要的代碼。

我可以設法對枚舉進行子類化,但不能對返回數組中所有類型的函數進行子類化。

任何幫助將不勝感激。

使用僅執行一次的閉包和AnyGenerator初始化all

@vacawama展示了如何使用僅執行一次的閉包以及enum的可失敗init(rawValue:)初始值設定項以通用方式初始化all數組。 前面提到的答案中方法的一個細微變化是交換顯式的while循環和附加有AnyGenerator數組:

enum Type: Int {
    case A = 0, B, C, D, E, F, G, H

    static let all: [Type] = {
        var rValue = 0
        return AnyGenerator<Type> {
            defer { rValue += 1 }
            return Type(rawValue: rValue)
        }.map{$0}
    }()
}

print(Type.all) 
    // [Type.A, Type.B, Type.C, Type.D, Type.E, Type.F, Type.G, Type.H]

這在rawValue只是++增加( 0, 1, 2, ... )的條件下rawValue


通過使enum符合SequenceType來初始化all

作為另一種選擇,由於您的rawValue是整數順序( ++ ),您可以讓您的enum符合SequenceType ,在這種情況下,只需使用.map即可輕松生成所有案例的數組

enum Type: Int, SequenceType {
    case A = 0, B, C, D, E, F, G, H
    
    init() { self = A } // Default (first) case intializer
    
    /* conform Type to SequenceType (here: enables only 
       simple (self.rawValue)...last traversing) */
    func generate() -> AnyGenerator<Type> {
        var rValue = self.rawValue
        return AnyGenerator {
            defer { rValue += 1 }
            return Type(rawValue: rValue)
        }
    }
    
    /* use the fact that Type conforms to SequenceType to neatly
     initialize your static all array */
     static let all = Type().map { $0 }
}

print(Type.all) 
    // [Type.A, Type.B, Type.C, Type.D, Type.E, Type.F, Type.G, Type.H]

應用此一致性來初始化靜態all數組可能有點矯枉過正,但如果您希望能夠使用符合SequenceType enum其他方面, all是一個合理的選擇

for typeCase in Type() {
    // treat each type ...
    print(typeCase, terminator: " ")
} // A B C D E F G H

for caseFromEAndForward in Type.E {
    print(caseFromEAndForward, terminator: " ")
} // E F G H

使用flatMap初始化基於rawValue范圍的rawValue

最后,作為@appzYourLife 簡潔解決方案的變體,如果您有很多情況,您可以在rawValue的范圍上使用flatMap操作來初始化靜態allValues數組,例如

enum Type: Int {
    case A = 0, B, C, D, E, F, G, H
    static let all = (A.rawValue...H.rawValue)
       .flatMap{ Type(rawValue: $0) }
}

print(Type.all) 
    // [Type.A, Type.B, Type.C, Type.D, Type.E, Type.F, Type.G, Type.H]

然而,這種方法實際上並沒有任何實際用途,因為一般大小方法( @vacawama:s或上面的SequenceType )對於許多情況的枚舉總是更可取的。 我可以看到的可能用例是,如果不同情況的rawValue是連續的,而不是簡單的++ ,例如,如果rawValue用於某些位掩碼

// ...
case A = 0, B = 2, C = 4, D = 8, E = 16, F = 32, G = 64, H = 128

上面的方法將使用一種通過rawValue的范圍強制執行的方法,其中少數實際上對應於實際情況。 有點浪費,但由於它是一次性靜態初始化,所以這應該不是問題。

為什么不簡單地向枚舉類型添加靜態屬性?

enum Type: Int {
    case A = 0, B, C
    static let all = [A, B, C]
}

如果您的rawValue是連續的Int ,您可以利用Type(rawValue:)初始值設定項將失敗並為非法值返回nil來自動計算Type.all而無需顯式列出值或設置范圍。 如果您向枚舉添加更多案例,它將自動調整:

enum Type: Int {
    case A, B, C, D, E, F, G, H, I, J, K
    static let all: [Type] = {
        var all: [Type] = []
        var value = 0
        while let e = Type(rawValue: value) {
            all.append(e)
            value += 1
        }
        return all
    }()
}

print(Type.all)
 [Type.A, Type.B, Type.C, Type.D, Type.E, Type.F, Type.G, Type.H, Type.I, Type.J, Type.K]

您可以定義一個包含枚舉所有可能值的靜態數組:

static let allValues = [A, B, C]

然后你可以在你想要的地方使用它:

var allEnumValues = Type.allValues

斯威夫特 5

現在你有了CaseIterable蘋果文檔 另一個話題

符合 CaseIterable 協議的類型通常是沒有關聯值的枚舉。 使用 CaseIterable 類型時,您可以使用類型的 allCases 屬性訪問該類型的所有案例的集合。

enum Direction: CaseIterable {
  case left
  case right
  case up
  case down
}

Direction.allCases.count
Direction.allCases.forEach { print($0) }

如果它也在其他類中使用,那么不要將它放在一個類中

class YourClass : Mappable {

}

enum Type: Int {
    case A = 0
    case B = 1
    case C = 2
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM