在Swift中存储数组中不同类型的闭包

时间:2022-10-26 17:02:35

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 })
    }
}