简体   繁体   English

保存任何枚举String类型的Swift数组

[英]Swift array holding any enum String type

How would I declare an array in Swift which can hold values of any enum String type? 我如何在Swift中声明一个数组,它可以保存任何enum String类型的值?

Here's what I want to do: 这就是我想要做的事情:

enum MyEnumType1: String {
    case Foo = "foo"
    case Bar = "bar"
}

enum MyEnumType2: String {
    case Baz = "baz"
}

// ...

// Compiler error: "Type of expression is ambiguous without more context"
var myArray = [ MyEnumType1.Bar, MyEnumType2.Baz ] 
//         ^ need to declare type here, but not sure of correct syntax 

// pass array over to a protocol which will iterate over the array accessing .rawValues

The two enum types are loosely related but definitely distinct and I need to keep the values separated in this instance, so lumping them all together in one enum and declaring the array of type MyAllIncludingEnumType is not desirable. 两个枚举类型松散相关,但绝对不同,我需要在这个实例中保持值分开,所以将它们全部集中在一个枚举中,并且声明类型为MyAllIncludingEnumType的数组是不可取的。

Or should I just declare an array of Strings and add the rawValues directly? 或者我应该只声明一个字符串数组并直接添加rawValues?

I could declare the array as [AnyObject] but then I'd have to type check each element before attempting to access the .rawValue , which isn't great either. 我可以将数组声明为[AnyObject]但之后我必须在尝试访问.rawValue之前键入check每个元素,这也不是很好。

Currently I'm only able to use Swift 1.2 on this project, as it's for an app which is already in the App Store and I need to be able to ship updates before Xcode 7 goes GM. 目前我只能在这个项目中使用Swift 1.2,因为它是已经在App Store中的应用程序,我需要能够在Xcode 7转到GM之前发布更新。

Or is there a cleaner but completely alternate solution to what I want to do? 或者,对于我想要做的事情,是否有更清洁但完全替代的解决方案?

An alternative to Kametrixom's answer is to make both enums conform to a common protocol. Kametrixom的答案的替代方案是使两个枚举符合通用协议。 Both automatically conform to RawRepresentable , because of the raw value of String : 两者都自动符合RawRepresentable ,因为String的原始值:

protocol RawRepresentable {
    typealias RawValue
    var rawValue: RawValue { get }
    ...
}

However, you cannot use this as the type stored in the array since RawRepresentable is a generic protocol. 但是,由于RawRepresentable是通用协议,因此不能将其用作存储在数组中的类型。 Instead you could do: 相反,你可以这样做:

protocol StringRepresentable {
    var rawValue: String { get }
}

enum EnumA: String, StringRepresentable {
    case A = "A"
}

enum EnumB: String, StringRepresentable {
    case B = "B"
}

let array: [StringRepresentable] = [EnumA.A, EnumB.B]
array[0].rawValue // A

Just think about it logically: You want to store multiple enums in an array, so it can be either this or that enum, which is just what an enum is! 从逻辑上考虑它:你想在一个数组中存储多个枚举,所以它可以是这个或那个枚举,这就是一个枚举! You can declare an new enum that has associated values of all the accepted other enums like so: 您可以声明一个新的枚举,该枚举具有所有已接受的其他枚举的关联值,如下所示:

enum A {
    case A1, A2
}

enum B {
    case B1, B2
}

enum All {
    case First(A)
    case Second(B)
}

Then you can create an array like this: 然后你可以创建一个这样的数组:

let array : [All] = [
    .First(.A1),
    .Second(.B2),
    .Second(.B1),
    .First(.A1)
]

Try The Below Code 试试下面的代码

enum MyEnumType1: String {
case Foo = "foo"
case Bar = "bar"
}

enum MyEnumType2: String {
case Baz = "baz"
}

var myArray: [Any] = [ MyEnumType1.Bar, MyEnumType2.Baz ]

If you use the array only to retrieve the rawValues of its elements, then you might simply store the rawValues in the array: 如果仅使用数组来检索其元素的rawValues,那么您可能只是将rawValues存储在数组中:

var myArray = [ MyEnumType1.Bar.rawValue, MyEnumType2.Baz.rawValue ]

If instead you want to retrieve the original enum from the array then you will need to type check the elements anyway, so var myArray: [Any] = ... will not make things worse. 如果你想要从数组中检索原始枚举,那么你将需要输入检查元素,所以var myArray: [Any] = ...不会让事情变得更糟。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM