Lets say I want to have an array of functions (closures) that I will later want to dispatch. I want all the closures to take an Array of any type as a single parameter.
让我们说我想要一个函数(闭包)的数组,我稍后将要发送。我希望所有的闭包都将任何类型的数组作为单个参数。
I tried:
我试过了:
var closureList: [(Array) -> Void]
This gives a compiler error: reference to generic type 'Array' requires arguments in <...>
这给出了编译器错误:对泛型类型'Array'的引用需要<...>中的参数
I don't want to store closure of a certain type of Array but any type of Array so I tried this:
我不想存储某种类型的数组的闭包,但任何类型的数组,所以我试过这个:
protocol GeneralArray {
}
extension Array: GeneralArray {
}
var closureList: [(GeneralArray) -> Void]
This compiles but when I try to append a closure:
这会编译,但是当我尝试追加一个闭包时:
func intArrayFunc([Int]) -> Void {
}
closureList.append(intArrayFunc)
I get a compiler error: cannot invoke 'append' with an argument list of type '(([Int]) -> Void)'.
我收到编译器错误:无法使用类型'(([Int]) - > Void)'的参数列表调用'append'。
Is there a way in swift to store closures that take different types as parameters in an array?
在swift中是否有一种方法可以存储在数组中使用不同类型作为参数的闭包?
1 个解决方案
#1
0
Using GeneralArray
is in this case almost the same as using [Any]
instead. Therefore a function of type [Int] -> Void
is not convertible to such a type.
在这种情况下,使用GeneralArray几乎与使用[Any]相同。因此,[Int] - > Void类型的函数不能转换为这种类型。
But in order to have a general way to handle any array a GeneralArray
would probably have a property of type [Any]
:
但是为了有一个处理任何数组的通用方法,GeneralArray可能会有[Any]类型的属性:
protocol GeneralArray {
var anyArray: [Any] { get }
}
extension Array: GeneralArray {
var anyArray: [Any] {
return self.map{ $0 as Any }
}
}
var closureList: [(GeneralArray) -> Void] = []
func intArrayFunc([Int]) -> Void {
}
So you have to wrap the function in a closure which is of type (GeneralArray) -> Void
:
所以你必须将函数包装在一个类型为(GeneralArray) - > Void的闭包中:
// wrapping the function in an appropriate closure
closureList.append({ array in intArrayFunc(array.anyArray.map{ $0 as! Int }) })
// with a helper function
closureList.append(functionConverter(intArrayFunc))
There are two possible helper functions which can "convert" the function:
有两种可能的“辅助函数”可以“转换”函数:
func functionConverter<T>(f: [T] -> Void) -> GeneralArray -> Void {
return { array in
// "safe" conversion to an array of type [T]
let arr: [T] = array.anyArray.flatMap{
if let value = $0 as? T {
return [value]
}
return []
}
f(arr)
}
}
func unsafeFunctionConverter<T>(f: [T] -> Void) -> GeneralArray -> Void {
return { array in
f(array.anyArray.map{ $0 as! T })
}
}
#1
0
Using GeneralArray
is in this case almost the same as using [Any]
instead. Therefore a function of type [Int] -> Void
is not convertible to such a type.
在这种情况下,使用GeneralArray几乎与使用[Any]相同。因此,[Int] - > Void类型的函数不能转换为这种类型。
But in order to have a general way to handle any array a GeneralArray
would probably have a property of type [Any]
:
但是为了有一个处理任何数组的通用方法,GeneralArray可能会有[Any]类型的属性:
protocol GeneralArray {
var anyArray: [Any] { get }
}
extension Array: GeneralArray {
var anyArray: [Any] {
return self.map{ $0 as Any }
}
}
var closureList: [(GeneralArray) -> Void] = []
func intArrayFunc([Int]) -> Void {
}
So you have to wrap the function in a closure which is of type (GeneralArray) -> Void
:
所以你必须将函数包装在一个类型为(GeneralArray) - > Void的闭包中:
// wrapping the function in an appropriate closure
closureList.append({ array in intArrayFunc(array.anyArray.map{ $0 as! Int }) })
// with a helper function
closureList.append(functionConverter(intArrayFunc))
There are two possible helper functions which can "convert" the function:
有两种可能的“辅助函数”可以“转换”函数:
func functionConverter<T>(f: [T] -> Void) -> GeneralArray -> Void {
return { array in
// "safe" conversion to an array of type [T]
let arr: [T] = array.anyArray.flatMap{
if let value = $0 as? T {
return [value]
}
return []
}
f(arr)
}
}
func unsafeFunctionConverter<T>(f: [T] -> Void) -> GeneralArray -> Void {
return { array in
f(array.anyArray.map{ $0 as! T })
}
}