【问题标题】:Swift array holding any enum String type包含任何枚举字符串类型的 Swift 数组
【发布时间】:2015-08-27 07:38:53
【问题描述】:

如何在 Swift 中声明一个可以保存任何enum String 类型值的数组?

这是我想做的:

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

这两种枚举类型松散相关但绝对不同,我需要在这种情况下将值分开,因此将它们集中在一个枚举中并声明 MyAllIncludingEnumType 类型的数组是不可取的。

或者我应该只声明一个字符串数组并直接添加 rawValues?

我可以将数组声明为 [AnyObject],但在尝试访问 .rawValue 之前,我必须对每个元素进行类型检查,这也不是很好。

目前我只能在这个项目上使用 Swift 1.2,因为它是针对已经在 App Store 中的应用程序,我需要能够在 Xcode 7 通用之前发布更新。

或者对于我想要做的事情,是否有更清洁但完全替代的解决方案?

【问题讨论】:

    标签: arrays swift enums


    【解决方案1】:

    Kametrixom 的替代方案是让两个枚举都符合一个通用协议。两者都自动符合RawRepresentable,因为String 的原始值:

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

    但是,您不能将其用作存储在数组中的类型,因为RawRepresentable 是一个通用协议。相反,您可以这样做:

    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
    

    【讨论】:

      【解决方案2】:

      从逻辑上考虑一下:你想在一个数组中存储多个枚举,所以它可以是这个或那个枚举,这就是枚举!您可以声明一个新的枚举,该枚举具有所有已接受的其他枚举的关联值,如下所示:

      enum A {
          case A1, A2
      }
      
      enum B {
          case B1, B2
      }
      
      enum All {
          case First(A)
          case Second(B)
      }
      

      然后你可以像这样创建一个数组:

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

      【讨论】:

      • 类似 Inception 的枚举。我喜欢它。
      【解决方案3】:

      试试下面的代码

      enum MyEnumType1: String {
      case Foo = "foo"
      case Bar = "bar"
      }
      
      enum MyEnumType2: String {
      case Baz = "baz"
      }
      
      var myArray: [Any] = [ MyEnumType1.Bar, MyEnumType2.Baz ]
      

      【讨论】:

        【解决方案4】:

        如果您只使用数组来检索其元素的 rawValues,那么您可以简单地将 rawValues 存储在数组中:

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

        如果您想从数组中检索原始枚举,那么无论如何您都需要对元素进行类型检查,因此var myArray: [Any] = ... 不会让事情变得更糟。

        【讨论】:

          猜你喜欢
          • 2014-07-23
          • 1970-01-01
          • 2020-08-16
          • 2014-08-09
          • 1970-01-01
          • 1970-01-01
          • 2016-03-06
          相关资源
          最近更新 更多