简体   繁体   中英

Swift 2.0: can not pass generic as a parameter

Why is this not working(even though the Container conforms to Unique protocol.) and how would the best workaround looks like?

protocol Unique {
    var uniqueId: String {get}
}

struct Container <T>: Unique {
    typealias UnderlyingObject = T
    var object: UnderlyingObject
    var uniqueId: String
}

func myFunc(protocolClosure: (Unique, Unique) -> Unique) {
    print("...")
}

func problemStartsHere<T,S,U>(paramClosure: (Container<T>, Container<S>) -> Container<U>) {
    myFunc(paramClosure)
}

在此输入图像描述

The problem here is one of variance, though not quite the variance you're looking for. Since you're passing a closure, you're really trying to make the method signature itself match, rather than the value passed into or return from of the method itself. This could raise problems if, say, myFunc tried invoking the closure using a parameter of a type other than Container<T> - and since it expects any Unique to be acceptable for that invocation, it would compile just fine.

The compiler shows this warning for a reason: myFunc expects a closure that works for any kind of Unique not just Container<T> .

You should use a generic version of the function instead:

func myFunc<A: Unique, B: Unique, C: Unique>(protocolClosure: (A, B) -> C) {
    print("...")
}

EDIT: Suppose you wanted to call your function problemStartsHere like this:

problemStartsHere { (c1: Container<Int>, c2: Container<Int>) -> Container<Int> in
    print(c1.object, c2.object)
    return c1
}

Notice that the function uses the Container -specific property object . Not how exactly should the compiler create a closure that works on any Unique ? It can't work like this, because it doesn't make sense, such a function cannot work on any Unique .

The problem is the return value. While you can pass any Container<...> to Unique parameter, the return value of type Unique can't be cast to Container<...> . That's why the closure type (Container<...>, Container<...>) -> Container<...> cannot be cast to (Unique, Unique) -> Unique .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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