简体   繁体   English

当Element是元组时,Extend Array受约束

[英]Extend Array constrained when Element is a tuple

Is there a way to extend an Array when the element is a type of tuple ? 当元素是一种元组时,有没有办法扩展数组?

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

}

This declaration returns 4 errors: 该声明返回4个错误:

  • Statement cannot begin with a closure expression 语句不能以闭包表达式开头
  • Braced block statements is an unused closure 支撑块语句是未使用的闭包
  • Expected '{' in extension 期待'{'的延伸
  • Expected identifier for type name 类型名称的预期标识符

I can't tell if the errors shown are accurate. 我不知道所显示的错误是否准确。 Any ideas? 有任何想法吗?

Swift 3 version of appzYourLife 's answer: Swift 3appzYourLife的回答:

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

Since (AFAIK) the Tuple type does not conform to a Protocol (and does not even have a name) it's very hard to do what you need. 由于(AFAIK) Tuple类型不符合Protocol (甚至没有名称),因此很难做到你需要的东西。

This is the closest I could get (maybe others can provide more elegant solutions). 这是我能得到的最接近的(也许其他人可以提供更优雅的解决方案)。

Typealias Typealias

First of all lets define a couple of typealiases 首先,我们定义几种类型

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

Yes, some readers now understand where I am going and probably don't like it... 是的,一些读者现在明白我要去哪里,可能不喜欢它......

I don't like it neither 我也不喜欢它

SequenceType 序列类型

Now let's extend the protocol SequenceType adding the foo method when the Element of the sequence is Tuple2 ... 现在让我们扩展协议SequenceType ,当序列的ElementTuple2时添加foo方法...

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

or Tuple3 或者Tuple3

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

Array 排列

Next lets define and populate an array of Tuple2 接下来,我们定义并填充Tuple2数组

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

Now the extension is applied and we can write 现在扩展已应用,我们可以编写

list.foo()

Disclaimer :D 免责声明:D

This does work only if the array is explicitly declared as [Tuple2] (or [Tuple3] ). 仅当数组显式声明为[Tuple2] (或[Tuple3] )时, [Tuple3]

Something like this does not work 像这样的东西不起作用

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

It's now possible in Swift 3.1. 它现在可以在Swift 3.1中使用。

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

You can't add specific typing like extension Array where Element == Int because this would transform the generic Array into a non-generic version. 您不能添加特定类型,例如extension Array where Element == Int因为这会将通用Array转换为非泛型版本。

You will see an error something like same-type requirement makes generic parameter 'Element' non-generic 您将看到类似于same-type requirement makes generic parameter 'Element' non-generic的错误, same-type requirement makes generic parameter 'Element' non-generic

Edit 编辑

It does actually seem legit (at least in Swift 2.2) to do: 它确实看起来合法(至少在Swift 2.2中):

 \n typealias tzTuple = (timeZoneName: String, formattedName: String) typealias tzTuple =(timeZoneName:String,formattedName:String) \n\n extension Array where Element: tzTuple { extension Array其中Element:tzTuple { \n\n } } \n 

You will have to see if this works in runtime though. 您将不得不看看它是否在运行时工作。

I was checking this in a Playground and at present, Playgrounds are not yet fully functional with Swift 2.2-dev 我在Playground中检查这个,目前,Playgrounds还没有完全适用于Swift 2.2-dev

I would suggest this instead: 我会建议这样做:

typealias tzTuple = (timeZoneName: String, formattedName: String)

extension Array {

  func formattedName(index: Int) -> String? {
    if self[index] is tzTuple {
      return (self[index] as! tzTuple).formattedName
    }
    return nil
  }
}

will allow you to do 会允许你这样做

let foo = [(timezoneName: "PST", formattedName: "Pacific Standard Time"),(timezoneName: "AEST", formattedName: "Australian Eastern Time")]
print(foo.formattedName(0))

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

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