【问题标题】:Handling enums with associated structs处理带有关联结构的枚举
【发布时间】:2020-10-27 20:45:52
【问题描述】:

我有一个枚举数组,其中包含相关的结构,如下所示:


struct TypeOne {
    let id = UUID()
    var image:UIImage
}

struct TypeTwo {
    let id = UUID()
    var image:UIImage
    var url:URL
}

enum Types {
    case one(a: TypeOne)
    case two(b: TypeTwo)
}

var array:[Types] = []

两个可能的结构共享变量;身份证和图片。有什么方法可以在不执行以下操作的情况下检索这些值?


switch array[0] {
    case .one(a: let a):
        print(a.id)
    case .two(b: let b):
        print(b.id)
}

由于两个结构中都存在这两个变量,我正在寻找这样的解决方案(如果存在):

print(array[0].(xxx).id)

【问题讨论】:

    标签: swift struct enums


    【解决方案1】:

    更新:我的回答可能会落空。你真的需要枚举吗?在我的解决方案中,消除了对枚举的需求。但是,如果您需要枚举,因为它包含其他重要信息,那么我的解决方案就不好了。如果您只是使用枚举,因此可以将两种类型都放在一个数组中,然后考虑使用 Typeable 的数组,而不是 Typeable 是我的解决方案的协议。

    是的,您可以使用类似这样的协议来定义一组通用的方法或字段:

    protocol Typeable {
        var id:UUID {get}
        var image:UIImage {get}
    }
    
    
    struct TypeOne:Typeable {
        let id = UUID()
        var image:UIImage
    }
    
    struct TypeTwo:Typeable {
        let id = UUID()
        var image:UIImage
        var url:URL
    }
    
    var array:[Typeable] = []
    
    let typeOne:TypeOne = //
    let typeTwo:TypeTwo = //
    
    array.append(typeOne)
    array.append(typeTwo)
    
    print(array[0].id)
    
    
    // to declare a function that takes a Typeable
    func myMethod<T:Typeable>(val:T) {
        print(val.id)
    }
    
    

    注意,我的协议名称不好,不符合命名准则。在不了解您的用例的情况下,我不确定什么是好名字。

    【讨论】:

      【解决方案2】:

      不知何故,您将不得不切换每种情况以提取相关值。但是,我们可以使其方便使用。我会从一个协议开始,这样我们的类型就有一个通用接口:

      protocol TypeProtocol {
          var id: UUID { get }
          var image: UIImage { get }
      }
      
      struct TypeOne: TypeProtocol {
          let id = UUID()
          var image: UIImage
      }
      
      struct TypeTwo: TypeProtocol {
          let id = UUID()
          var image: UIImage
          var url: URL
      }
      

      您的枚举可以大致相同,但我们可以使用一些方便的属性对其进行扩展。

      enum Types {
          case one(a: TypeOne)
          case two(b: TypeTwo)
      }
      
      extension Types: TypeProtocol {
      
          var id: UUID {
              type.id
          }
      
          var image: UIImage {
              type.image
          }
      
          var type: TypeProtocol {
              switch self {
              case .one(let a):
                  return a
              case .two(let b):
                  return b
              }
          }
      }
      

      最后,给定一个类型数组,我们可以使用便利属性来访问底层数据:

      var array: [Types] = []
      
      array.forEach { print($0.id) }
      array.forEach { print($0.type.id) }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-01-12
        • 1970-01-01
        • 2019-08-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-23
        • 2023-04-05
        相关资源
        最近更新 更多