创建不同枚举的集合



是否可以创建不同枚举类型的数组?

例如:

MyEnums.swift:

class MyEnums {
    enum FirstEnum: String {
        case Type1, Type2, Type3
    }
    enum SecondEnum: String {
        case Type1, Type2, Type3
    }
}

IteratorManager.swift:

class IteratorManager {
    var enumsArray = [MyEnums]()
    func iterate() {
        for e in enumsArray {
            print(e.rawValue)
        }
    }
}

我尝试了许多解决方案-扩展,协议,在类中分组(如上面的例子)在struct或enum -但没有工作

是的,但是你应该知道你是怎么做的。

枚举创建一个具体的Type。Swift是类型安全语言。FirstEnum的数组不允许包含非FirstEnum类型的项。

然而,有两种方法可以实现这一点。 1。资源协议 2。类型的谎言

我将采用这两种方法,但我永远不会推荐使用第二种选择,尽管它看起来简单而难以捉摸。

我将从第二个开始。

enum FirstEnum: String {
    case Type1, Type2, Type3
}
enum SecondEnum: String {
    case Type1, Type2, Type3
}

让我们创建一些具体类型的枚举。

let firstEnum1 = FirstEnum.Type1
let firstEnum2 = FirstEnum.Type2
let secondEnum1 = SecondEnum.Type3

让我们用第二个选项来包装它们:

let a:[Any] = [firstEnum1, firstEnum2, secondEnum1] //works

让我们看看如何在后面提取它:

for index in a {
 if let a = index as? FirstEnum {  //This is bad
    print(a.rawValue)
 }
 if let a = index as? SecondEnum { //Aweful
    print(a.rawValue)
 }
}

必须将其强制转换回插入的值。我们必须使用期望,谁知道我们返回的可能是String而不是Enum。因为任意可以取任意。

让我们看看如何通过第一个选项来解决这个问题:

let b:[RawRepresentable] = [firstEnum1, secondEnum1]  //Cant do so because of Associated Type

这段代码不能工作,因为它的rawrepresable是一个不完整的类型。所以我们需要定义我们自己的协议。

protocol CustomStringRepresentableEnum {
   var rawValue: String { get }
}

当然,我们的枚举支持rawValue,所以我们可以追溯建模这个协议。

 extension FirstEnum: CustomStringRepresentableEnum { }
 extension SecondEnum: CustomStringRepresentableEnum { }

现在我们可以创建一个具体已知类型的数组。

let b:[CustomStringRepresentableEnum] = [firstEnum1, firstEnum2, secondEnum1]

这很好,因为我们不允许输入任何东西,除了符合协议的东西。这是正确的类型和约束,编译器将帮助你很多,以防止坏的事情发生,如错误的类型转换。

让我们用它来证明我们写了一些好的代码。

for index in b {
    print(index.rawValue)
}

就是这样。你可以在一个数组中有不同的枚举但它们必须是齐次的。你可以用Any欺骗编译器,写出丑陋的代码,或者使用协议和泛型写出有效的和健壮的代码。选择权在你。

@kandelvijaya谢谢你的回答。

到目前为止,我已经开发了一些基于属性的enum初始化的其他态度:

MyEnums.swift:

enum MyEnums {
    enum FirstEnum: String {
        case Type1, Type2, Type3
    }
    enum SecondEnum: String {
        case Type1, Type2, Type3
    }
    case First(FirstEnum)
    case Second(SecondEnum)
    var rawValue: String {
        switch self {
        case .First(let e):
            return e.rawValue
        case .Second(let e):
            return e.rawValue
        }
    }
}

IteratorManager.swift:

class IteratorManager {
    var enumsArray = [MyEnums]()
    func iterate() {
        for e in enumsArray {
            print(e.rawValue)
        }
    }
}

填充数组并迭代:

let iteratorManager = IteratorManager()
iteratorManager.enumsArray = [MyEnums.First(MyEnums.FirstEnum.Type1), MyEnums.Second(MyEnums.SecondEnum.Type2)]
iteratorManager.iterate()

它也是类型安全的(不像Any的解决方案)。

此外,我们可以定义一个示例协议:

protocol MyEnumsProtocol {
    var processedValue: String { get }
    static func typeGeneralDescription() -> String
}

实现它:

enum MyEnums {
    enum FirstEnum: String, MyEnumsProtocol {
        case Type1, Type2, Type3
        var processedValue: String {
            return "-=(self)-="
        }
        static func typeGeneralDescription() -> String {
            return "First enum type"
        }
    }
    enum SecondEnum: String, MyEnumsProtocol {
        case Type1, Type2, Type3
        var processedValue: String {
            return "-=(self)-="
        }
        static func typeGeneralDescription() -> String {
            return "Second enum type"
        }
    }
    case First(FirstEnum)
    case Second(SecondEnum)
    var rawValue: String {
        switch self {
        case .First(let e):
            return e.rawValue
        case .Second(let e):
            return e.rawValue
        }
    }
    var subTypeDesc: String {
        switch self {
        case .First(let e):
            return "(FirstEnum.typeGeneralDescription()): (e.processedValue)"
        case .Second(let e):
            return "(SecondEnum.typeGeneralDescription()): (e.processedValue)"
        }
    }
}

并像这样使用:

let subTypeDesc = iteratorManager.enumsArray.first?.subTypeDesc

相关内容

  • 没有找到相关文章

最新更新