How to limit the general sequence parameter for a tuple in Swift 3?

In Swift 2, I was able to write a function that worked in any order, 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 a limited type was especially useful so that it could accept dictionaries, such as [String:Int]since their sequence type consisted of tuples.

In Swift 3, I believe that 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 an attempt to pass in [String:Int], for example:, test(input: ["a": 1, "b": 2])causes an error:

General parameter 'T' cannot be displayed

, Swift 3 (Key, Value) , , . , , where T.Iterator.Element == String, - [String] .

-, , Swift 3?

+1
2

.

Dictionary Sequence:

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

DictionaryIterator:

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

, Dictionary T.Iterator.Element (key: Key, value: Value), (Key, 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

, - , .

+1

(SR-992), , .

, (String, Int) (key: String, value: Int), [String : Int] - test(input:) , (key: String, value: Int), . map, "" , test.

// Overload to deal with [String : Int] inputs โ€“ workaround for a bug.
func test<T: Sequence>(input: T) where T.Iterator.Element == (key: String, value: Int) {
    // 'Erase' the tuple labels with a lazily evaluated map(_:)
    // and pass the sequence onto the original implementation of test(input:)
    test(input: AnySequence(input.lazy.map{($0.key, $0.value)}))
}

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

let d = ["foo" : 5]
let a = [("key", 3)]

test(input: d) // prints: foo = 5
test(input: a) // prints: key = 3

, , , . , - .

+1

Source: https://habr.com/ru/post/1657213/


All Articles