【问题标题】:Can I extend Tuples in Swift?我可以在 Swift 中扩展元组吗?
【发布时间】:2015-04-03 18:04:55
【问题描述】:

我想在 Swift 中为(例如)两个值的元组编写一个扩展。比如我想写这个swap方法:

let t = (1, "one")
let s = t.swap

使得s 的类型为(String, Int),值为("one", 1)。 (我知道我可以很容易地实现 swap(t) 函数,但这不是我感兴趣的。)

我可以这样做吗?我似乎无法在 extension 声明中写入正确的类型名称。

另外,我想答案是一样的,我可以让一个 2 元组采用给定的协议吗?

【问题讨论】:

  • Swift documentation for Types 区分命名类型复合类型。命名类型可以扩展,但元组(和函数)是复合类型。
  • 谢谢,马丁。看起来这是一个明确的“不”,那么。你能把它变成一个答案让我接受吗?
  • 使用元组可以做的最多的自定义是命名参数并为其使用typealias。对于更复杂的事情,您应该使用structs 或定义全局函数(可能使用泛型)
  • man...能够在类型别名上定义扩展名将是令人兴奋的...我准备接受某种形式的强制(使用与元组中声明的相同的命名或其他) ...

标签: swift tuples swift-extensions swift-protocols


【解决方案1】:

您不能在 Swift 中扩展元组类型。 根据 Types,有命名类型(其中 可以扩展)和复合类型。元组和函数是复合的 类型。

另请参阅(已添加重点):

Extensions
扩展将新功能添加到现有的 类、结构或枚举类型

【讨论】:

    【解决方案2】:

    正如上面的回答所说,你不能在 Swift 中扩展元组。但是,您可以做的不仅仅是将元组装箱到 classstructenum 中并扩展它。

    struct TupleStruct {
        var value: (Int, Int)
    }
    extension TupleStruct : Hashable {
        var hashValue: Int {
            return hash()
        }
        func hash() -> Int {
            var hash = 23
            hash = hash &* 31 &+ value.0
            return hash &* 31 &+ value.1
        }
    }
    
    func ==(lhs: TupleStruct, rhs: TupleStruct) -> Bool {
        return lhs.value == rhs.value
    }
    

    附带说明,在 Swift 2.2 中,最多包含 6 个成员的元组现在是 Equatable

    【讨论】:

      【解决方案3】:

      详情

      • Xcode 11.2.1 (11B500)、Swift 5.1

      解决方案

      struct Tuple<T> {
          let original: T
          private let array: [Mirror.Child]
          init(_ value: T) {
              self.original = value
              array = Array(Mirror(reflecting: original).children)
          }
      
          func getAllValues() -> [Any] { array.compactMap { $0.value } }
          func swap() -> (Any?, Any?)? {
              if array.count == 2 { return (array[1].value, array[0].value) }
              return nil
          }
      }
      

      用法

      let x = (1, "one")
      let tuple = Tuple(x)
      print(x)                                        // (1, "one")
      print(tuple.swap())                             // Optional((Optional("one"), Optional(1)))
      if let value = tuple.swap() as? (String, Int) {
          print("\(value) | \(type(of: value))")      // ("one", 1) | (String, Int)
      }
      

      【讨论】:

        猜你喜欢
        • 2016-02-05
        • 2022-12-03
        • 1970-01-01
        • 2016-08-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多