swift - 如何将通用序列参数约束为 Swift 3 中的元组?

标签 swift generics swift3

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

func test<T: SequenceType where 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) where T.Iterator.Element == (String, Int) {
    for (k, v) in input {
        print(k, "=", String(v))
    }
}

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

Generic parameter 'T' could not be inferred

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

我是否遗漏了什么,或者这可能是 Swift 3 中的回归?

最佳答案

一个有趣的例子。

让我们检查一下 Dictionary 的关于符合 Sequence 的定义:

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

然后是DictionaryIterator:

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

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

如果您将函数重写为:

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

这个有效:

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

但这不起作用:

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

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

关于swift - 如何将通用序列参数约束为 Swift 3 中的元组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39529357/

相关文章:

swift - 从一个 UINavigationController 转到另一个 UINavigationController (Swift iOS 9, xcode 7)

c# - 通用容器 : why do I need an interface?

ios - 在 Swift 3 和 iOS 中管理 Sqlite 数据库文件(从本地和/或 bundle 复制到应用程序)

ios - 无法将 (Timer!) -> Void 转换为 ((CFRunLoopTimer?) ->Void)! - 将 NSTimer 扩展转换为 Swift 3

ios - swift : numberOfSectionsInCollectionView not working?

ios - 闭包执行

swift - 使用 mapbox 自定义 MGLPolyline

ios - keyboardWillShow 第一次显示奇怪的高度

java: HashMap<String, int> 不工作

javascript - 如何排除不需要的后代?