我在 XCode 7.3.1 上使用 Swift 2.2 并尝试从另一个 Generic
函数调用一个 Generic
函数。
代码
class Thing1 {
let variable: SomeProtocol
init<A: SomeProtocol>(variable: A) {
self.variable = variable
self.add1(self.variable)
}
func add1<A: SomeProtocol>(stuff: A) {
let thing: Thing2 = Thing2()
thing.add2(stuff)
}
}
class Thing2 {
func add2<A: SomeProtocol>(stuff: A) {
}
}
protocol SomeProtocol { }
add1("a") // Cannot invoke 'add1' with an argument list of type '(String)'
add1(4) // Cannot invoke 'add1' with an argument list of type '(Int)'
我得到了错误。
'Cannot invoke add with an argument of list type '(Whatever type I used to call the function)''
最佳答案
问题是 abstract types in Swift don't necessarily conform to themselves – 因此,您不能将 SomeProtocol
类型的东西用作符合 SomeProtocol
的具体类型的东西(这是您的 add1
通用函数期望的参数)。
因此,在您的情况下,最简单的解决方案就是使用通用 variable
参数,而不是 variable
属性,因为它是通用的,所以它被键入为具体的符合 SomeProtocol
的东西,因此可以将其传递到您的 add1
函数中:
init<A: SomeProtocol>(variable: A) {
self.variable = variable
add1(variable)
}
然而,为了防止以后出现此类问题,您可能需要考虑将您的类设为通用类,假设您的 variable
属性在给定类的整个生命周期中都应该是常量类型Thing1
实例:
class Thing1<A:SomeProtocol> {
let variable: A
init(variable: A) {
self.variable = variable
add1(variable)
}
func add1(stuff: A) {
let thing = Thing2()
thing.add2(stuff)
}
}
或者,您可以重构您的代码以使用抽象类型 SomeProtocol
,这将允许您使用符合 SomeProtocol
的任何类型>(例如,允许您将不同的 Thing1
实例与数组中的不同 variable
类型混合):
class Thing1 {
let variable: SomeProtocol
init(variable: SomeProtocol) {
self.variable = variable
add1(variable)
}
func add1(stuff: SomeProtocol) {
let thing = Thing2()
thing.add2(stuff)
}
}
class Thing2 {
func add2(stuff: SomeProtocol) {
}
}
虽然您应该始终意识到使用抽象类型带来的额外成本,see this great WWDC talk for more info .
关于ios - Swift 通用函数调用另一个通用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38899679/