Расширение типизированных массивов (таких примитивных типов, как Bool) в Swift 3?
Раньше в Swift 2.2 я мог:
extension _ArrayType where Generator.Element == Bool{
var allTrue : Bool{
return !self.contains(false)
}
}
который продолжается [Bool]
с помощью .allTrue
. Например.
[true, true, false].allTrue == false
Но в Swift 3.0 я получаю эту ошибку:
необъявленный тип _ArrayType
Поэтому я попытался переключить его на Array
и используя новое ключевое слово Iterator
extension Array where Iterator.Element == Bool
var allTrue : Bool{
return !self.contains(false)
}
}
Но у меня другая ошибка, жалующаяся на то, что я заставляю элемент быть не общим
Требование к одному типу делает общий параметр "Элемент" не общим
Я также пробовал решения на этом 2-летнем посту, но безрезультатно.
Итак, как можно расширить массивы примитивных типов, таких как Bool в Swift 3?
Ответы
Ответ 1
Просто добавьте коллекцию или последовательность
extension Collection where Iterator.Element == Bool {
var allTrue: Bool { return !contains(false) }
}
Тестирование игровой площадки:
[true, true,true, true,true, true].allTrue // true
[true, true,false, true,true, true].allTrue // false
Другой вариант - создать собственный протокол и расширить его:
protocol BoolConvertible {
var bool: Bool { get }
}
extension Bool: BoolConvertible {
var bool: Bool { return self }
}
extension Array where Element: BoolConvertible {
var allTrue: Bool { return !contains{!$0.bool} }
}
Ответ 2
Apple заменила _ArrayType
на _ArrayProtocol
в Swift 3.0 (см. исходный код Apple Swift на GitHub), чтобы вы могли сделать то же самое вы сделали в Swift 2.2, выполнив следующие действия:
extension _ArrayProtocol where Iterator.Element == Bool {
var allTrue : Bool { return !self.contains(false) }
}
Ответ 3
Начиная с Swift 3.1 (включенного в Xcode 8.3), теперь вы можете расширить тип с конкретным ограничением:
extension Array where Element == Bool {
var allTrue: Bool {
return !contains(false)
}
}
Вы также можете расширить Collection
вместо Array
, но вам нужно ограничить Iterator.Element
, а не только Element
.
Ответ 4
Расширение _ArrayProtocol
или Collection
не работает для меня, но Sequence
сделал.
public extension Sequence where Iterator.Element == String
{
var allTrue: Bool { return !contains(false)
}