为什么这不起作用(即使Container符合Unique协议。)以及最好的解决方法是什么样的?
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)
}
答案 0 :(得分:1)
这里的问题是差异,但不是你正在寻找的差异。由于你传递了一个闭包,你真的试图使方法签名本身匹配,而不是传递给方法本身或从方法本身返回的值。如果myFunc
尝试使用Container<T>
以外的类型的参数调用闭包,并且由于它期望任何Unique
可以接受该调用,这可能会引发问题,它会编译得很好。
答案 1 :(得分:1)
编译器出于以下原因显示此警告:myFunc
期望一个适用于任何类型Unique
的闭包,而不仅仅是Container<T>
。
您应该使用该函数的通用版本:
func myFunc<A: Unique, B: Unique, C: Unique>(protocolClosure: (A, B) -> C) {
print("...")
}
编辑:假设您想要像这样调用您的函数problemStartsHere
:
problemStartsHere { (c1: Container<Int>, c2: Container<Int>) -> Container<Int> in
print(c1.object, c2.object)
return c1
}
请注意,该函数使用Container
特定属性object
。不是编译器应该如何创建一个适用于任何Unique
的闭包?它不能像这样工作,因为它没有意义,这样的功能不适用于任何Unique
。
答案 2 :(得分:1)
问题是返回值。虽然您可以将Container<...>
传递给Unique
参数,但Unique
类型的返回值无法转换为Container<...>
。这就是封闭类型(Container<...>, Container<...>) -> Container<...>
无法转换为(Unique, Unique) -> Unique
的原因。