【问题标题】:Storing closures of different types in array in Swift在 Swift 中将不同类型的闭包存储在数组中
【发布时间】:2015-09-04 22:32:33
【问题描述】:

假设我想要一组函数(闭包),稍后我将要分派这些函数(闭包)。我希望所有闭包都将任何类型的 Array 作为单个参数。

我试过了:

var closureList: [(Array) -> Void] 

这会导致编译器错误:对泛型类型“数组”的引用需要 <...>

中的参数

我不想存储某种类型的 Array 但任何类型的 Array 的闭包,所以我尝试了这个:

protocol GeneralArray {

}

extension Array: GeneralArray {

}

var closureList: [(GeneralArray) -> Void]

这可以编译,但是当我尝试附加一个闭包时:

func intArrayFunc([Int]) -> Void {

}

closureList.append(intArrayFunc)

我收到一个编译器错误:无法使用类型为“(([Int]) -> Void)”的参数列表调用“附加”。

有没有办法在 swift 中将不同类型作为参数的闭包存储在数组中?

【问题讨论】:

标签: swift generics


【解决方案1】:

在这种情况下使用GeneralArray 与使用[Any] 几乎相同。因此[Int] -&gt; Void 类型的函数不能转换为这种类型。

但是为了有一个通用的方法来处理任何数组,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 {

}

因此,您必须将函数包装在 (GeneralArray) -&gt; 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))

有两种可能的辅助函数可以“转换”函数:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-09
    • 1970-01-01
    • 1970-01-01
    • 2013-06-01
    • 1970-01-01
    相关资源
    最近更新 更多