如何在Swift 3中将通用序列参数约束为一个元组? [英] How to constrain a generic sequence parameter to a tuple in Swift 3?

查看:121
本文介绍了如何在Swift 3中将通用序列参数约束为一个元组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Swift 2中,我能够编写一个函数,它可以按照任何顺序操作,例如(String,Int)。它看起来像这样:

  func test< T:SequenceType其中T.Generator.Element ==(String,Int)> ;(input,T){
for(k,v)in input {
print(k,=,String(v))
}
}

使用元组作为约束类型尤其有用,因此它可以接受字典,如 [String:Int] ,因为它们的序列类型由元组组成。

在Swift 3中,我相信一个类似的函数是:

  func test< T:Sequence>(input:T)其中T.Iterator.Element ==(String,Int){
为输入{
print(k,=,String(v))
}
}
中的(k,v)

但试图传入 [String:Int] ,例如: test(输入:[a:1,b:2]),导致错误:


通用参数'T'无法推断



就我所知,Swift 3中的字典仍然使用(Key,Value)元组作为它们的迭代器类型,所以我认为这应该起作用。事实上,如果我不使用单个类型作为受约束的迭代器类型,例如,其中T.Iterator.Element == String ,我可以传入诸如一个 [字符串] ,它可以正常工作。



有什么我不知道的,或者可能是在Swift 3中进行回归?

解决方案

一个有趣的例子。检查 Dictionary 关于符合顺序的定义:

  public func makeIterator() - > DictionaryIterator< Key,Value> 

然后 DictionaryIterator

  public mutating func next() - > (键:键,值:值)? 

因此,对于 Dictionary T.Iterator.Element 似乎是(key:Key,value:Value),而不是(Key ,价值)



如果您将函数重写为:

  func test< T:Sequence>(input:T)其中T.Iterator.Element ==(key:String,value:Int){
for(k,v)in input {
print(k,=,String(v))
}
}

这样做:

  test(输入:[a:1,b:2] )

但这不起作用:

<$ (无法推断出通用参数'T')
pre> test(input:[(a,1),(b,2)])// - &

我不确定这是一个预期的功能还是某种回归,或者只是一个错误。


In Swift 2, I was able to write a function which operated on any sequence of, for example, (String, Int). It looked something like this:

func test<T: SequenceType where T.Generator.Element == (String, Int)>(input: T) {
    for (k, v) in input {
        print(k, "=", String(v))
    }
}

Using a tuple as the constrained type was particularly useful so that it could accept dictionaries, such as [String:Int], as their sequence type consisted of tuples.

In Swift 3, I believe a similar function would be:

func test<T: Sequence>(input: T) where T.Iterator.Element == (String, Int) {
    for (k, v) in input {
        print(k, "=", String(v))
    }
}

But attempting to pass in a [String:Int], for example: test(input: ["a": 1, "b": 2]), causes the error:

Generic parameter 'T' could not be inferred

As far as I can tell, dictionaries in Swift 3 still use a (Key, Value) tuple as their iterator type, so I think this should work. In fact, if I don't use a single type as the constrained iterator type, such as where T.Iterator.Element == String, I can pass in something such as a [String] and it works correctly.

Is there something I'm missing, or might this be a regression in Swift 3?

解决方案

An interesting example.

Let's check the definition of Dictionary about conforming to Sequence:

public func makeIterator() -> DictionaryIterator<Key, Value>

And then DictionaryIterator:

public mutating func next() -> (key: Key, value: Value)?

So, for Dictionary, T.Iterator.Element seems to be (key: Key, value: Value), not (Key, Value).

If you rewrite your function as:

func test<T: Sequence>(input: T) where T.Iterator.Element == (key: String, value: Int) {
    for (k, v) in input {
        print(k, "=", String(v))
    }
}

this works:

test(input: ["a": 1, "b": 2])

But this does not work:

test(input: [("a", 1),("b",2)]) //->Generic parameter 'T' could not be inferred

I'm not sure this is an intended feature or some sort of regression, or simply a bug.

这篇关于如何在Swift 3中将通用序列参数约束为一个元组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆