【问题标题】:Extend Array constrained when Element is a tuple当 Element 是元组时,扩展受约束的数组
【发布时间】:2015-12-18 21:39:24
【问题描述】:

当元素是元组类型时,有没有办法扩展数组?

public extension Array where Element: (timeZoneName: String, formattedName: String){

}

此声明返回 4 个错误:

  • 语句不能以闭包表达式开头
  • 花括号语句是未使用的闭包
  • 扩展中应为“{”
  • 类型名称的预期标识符

我无法判断显示的错误是否准确。 有什么想法吗?

【问题讨论】:

  • 你为什么不创建一个类?
  • 你的意思是 Array 的子类吗?
  • 只是一个具有这两个属性的新类

标签: arrays swift generics swift2


【解决方案1】:

Swift 3appzYourLife的回答:

extension Sequence where Iterator.Element == Tuple2 {
    func foo() {}
}

【讨论】:

    【解决方案2】:

    现在可以在 Swift 3.1 中使用。

    extension Array where Element == (String, String) {
        ...
    }
    

    【讨论】:

      【解决方案3】:

      由于 (AFAIK) Tuple 类型不符合 Protocol(甚至没有名称),因此很难满足您的需求。

      这是我能得到的最接近的(也许其他人可以提供更优雅的解决方案)。

      类型别名

      首先让我们定义几个类型别名

      typealias Tuple2 = (Any, Any)
      typealias Tuple3 = (Any, Any, Any)
      

      是的,一些读者现在明白我要去哪里了,可能不喜欢它......

      我也不喜欢

      序列类型

      现在让我们扩展协议SequenceType,当序列的ElementTuple2时添加foo方法...

      extension SequenceType where Generator.Element == Tuple2 {
          func foo() {}
      }
      

      Tuple3

      extension SequenceType where Generator.Element == Tuple3 {
          func foo() {}
      }
      

      数组

      接下来让我们定义和填充Tuple2的数组

      let list: [Tuple2] = [(1,2)]
      

      现在扩展应用了,我们可以写了

      list.foo()
      

      免责声明:D

      只有当数组被显式声明为[Tuple2](或[Tuple3])时,这才有效。

      这样的事情不起作用

      let list = [(1,2)]
      list.foo() // compile error
      

      【讨论】:

        【解决方案4】:

        您不能添加像 extension Array where Element == Int 这样的特定类型,因为这会将泛型 Array 转换为非泛型版本。

        你会看到类似same-type requirement makes generic parameter 'Element' non-generic的错误

        编辑

        这样做实际上看起来是合法的(至少在 Swift 2.2 中):

        typealias tzTuple = (timeZoneName: String, formattedName: String) 扩展数组其中元素:tzTuple { }

        不过,您必须看看这在运行时是否有效。

        我在 Playground 中检查了这一点,目前,Playgrounds 还没有与 Swift 2.2-dev 完全兼容

        我会建议这样做:

        typealias tzTuple = (timeZoneName: String, formattedName: String) 扩展数组 { func formattedName(index: Int) -> String? { 如果 self[index] 是 tzTuple { return (self[index] as!tzTuple).formattedName } 返回零 } }

        会让你这样做

        let foo = [(timezoneName: "PST", formattedName: "太平洋标准时间"),(timezoneName: "AEST", formattedName: "澳大利亚东部时间")] 打印(foo.formattedName(0))

        【讨论】:

        • 那太好了,我目前正在使用 swift 2.1。希望下一个Xcode自带2.2
        • 一年过去了,Swift 发生了很多变化。与其对我的原始答案投反对票,不如创建一个新的正确答案或对替代答案投赞成票。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多