2015-09-04 2 views
0

Допустим, у меня есть массив функций (закрытий), которые я позже захочу отправить. Я хочу, чтобы все блокировки принимали Array любого типа в качестве единственного параметра.Сохранение замыканий различных типов в массиве в Swift

Я пробовал:

var closureList: [(Array) -> Void] 

Это дает ошибку при компиляции: ссылка на общий тип «Массив» требует аргументов в < ...>

Я не хочу, чтобы сохранить закрытие определенного тип массива, но любого типа массива, поэтому я попытался это:

protocol GeneralArray { 

} 

extension Array: GeneralArray { 

} 

var closureList: [(GeneralArray) -> Void] 

компилируется, но когда я пытаюсь добавить замыкание:

func intArrayFunc([Int]) -> Void { 

} 

closureList.append(intArrayFunc) 

Я получаю ошибку компилятора: не могу вызвать 'append' с помощью списка аргументов типа '(([Int]) -> Void)'.

Есть ли способ быстро закрыть хранилища, которые принимают разные типы в качестве параметров в массиве?

+1

дженерики. (GeneralArray) -> Пустота ожидается, и вы проходите (Int) -> Void. Попробуйте func intArrayFunc ([GeneralArray]) -> Пустота. Проверьте это http://stackoverflow.com/questions/29829763/how-to-define-array-of-closures-in-swift – jarryd

ответ

0

Использование GeneralArray в этом случае почти такое же, как с использованием [Any]. Поэтому функция типа [Int] -> 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) -> 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 }) 
    } 
} 
Смежные вопросы