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.