ios 具有关联值的枚举不符合CaseIterable并引发错误

vfh0ocws  于 2022-12-01  发布在  iOS
关注(0)|答案(3)|浏览(131)

下面的枚举可以正常工作,没有任何错误。

enum EnumOptions: CaseIterable {
        case none
        case mild
        case moderate
        case severe
        case unmeasurable
}

当我尝试向其中一个事例添加关联值时,它抛出以下错误“类型”EnumOptions“不符合协议”CaseIterable“。是否要添加协议存根?”

enum OedemaOptions: CaseIterable {
        case none
        case mild
        case moderate
        case severe
        case unmeasurable(Int)
}

添加存根之后,

enum OedemaOptions: CaseIterable {
        typealias AllCases = <#type#>

        case none
        case mild
        case moderate
        case severe
        case unmeasurable(Int)

由于只有一个案例具有关联值,而不是所有案例,因此应在占位符中填充什么以使枚举符合CaseIterable?

4uqofj5v

4uqofj5v1#

自动合成不适用于具有关联值的枚举。您需要提供allCases属性的自定义实现。请尝试,

enum OedemaOptions: CaseIterable {
    static var allCases: [OedemaOptions] {
        return [.none, .mild, .moderate, .severe, .unmeasurable(-1)]
    }
    
    case none
    case mild
    case moderate
    case severe
    case unmeasurable(Int)
}
9bfwbjaz

9bfwbjaz2#

你忘了计算所有的18446744073709551616
此外,每个都是Option,而不是Options

static var allCases: [OedemaOption] {
  [.none, .mild, .moderate, .severe]
  + (.min...(.max)).map(unmeasurable)
}
o7jaxewo

o7jaxewo3#

编译器不支持 CaseIterable 在具有关联值的情况下的自动合成。

这是 CaseIterable 的替代解决方案

import Foundation

protocol CustomCaseIterable {
    associatedtype AllCustomCases: Hashable

    static var allCustomCases: [AllCustomCases: Self] { get }
}

extension CustomCaseIterable {
    init(_ string: String?, defaultCase: Self) {
        self = Self(string) ?? defaultCase
    }

    init?(_ string: String?) {
        guard
            let string = string,
            let caseValue = Self.allCustomCases.first(where: { "\($0.0)" == string })?.value
        else {
            return nil
        }
        self = caseValue
    }
}

示例

enum MyEnum {
    case one(Bool)
    case two(Int)
    case three(String)
    case four
}

extension MyEnum: CustomCaseIterable {
    static var allCustomCases: [String : Self] = [
        "one_true": .one(true),
        "two_zero": .two(.zero),
        "three_empty": .three(""),
        "four": .four
    ]
}

for (key, _) in MyEnum.allCustomCases {
    print(key)
}

将该概念扩展到RawRepresentable

extension CustomCaseIterable where AllCustomCases: RawRepresentable {
    init(_ string: String?, defaultCase: Self) {
        self = Self(string) ?? defaultCase
    }

    init?(_ string: String?) {
        guard
            let string = string,
            let caseValue = Self.allCustomCases.first(where: { "\($0.0.rawValue)" == string })?.value
        else {
            return nil
        }
        self = caseValue
    }
}

示例

enum MapStyle {
    case primary(border: Bool)
    case secondary(border: Bool)
    case placeholder
}

enum JSONMapStyle: String, CaseIterable {
    case primary
    case primaryWithBorder = "PRIMARY_WITH_BORDER"
    case secondary
    case secondaryWithBorder = "SECONDARY_WITH_BORDER"
    case placeholder
}

extension MapStyle: CustomCaseIterable {
    static var allCustomCases: [JSONMapStyle: MapStyle] = [
        .primary: .primary(border: false),
        .primaryWithBorder: .primary(border: true),
        .secondary: .secondary(border: false),
        .secondaryWithBorder: .secondary(border: true),
        .placeholder: .placeholder
    ]
}

for (key, _) in MapStyle.allCustomCases {
    print(key.rawValue)
}

相关问题