在 Swift 3 中扩展类型化数组(基本类型,如 Bool)?

Extending typed Arrays (of primitive types like Bool) in Swift 3?

以前在 Swift 2.2 中我可以做到:

extension _ArrayType where Generator.Element == Bool{
    var allTrue : Bool{
        return !self.contains(false)
    }
}

.allTrue 扩展了 [Bool]。例如

[true, true, false].allTrue == false

但是在 Swift 3.0 中我收到了这个错误:

undeclared type _ArrayType


所以我尝试将其切换为 Array 并使用新关键字 Iterator

extension Array where Iterator.Element == Bool
    var allTrue : Bool{
        return !self.contains(false)
    }
}

但是我遇到了一个不同的错误,抱怨我强制元素是非通用的

Same-type requirement makes generic parameter 'Element' non-generic


我也尝试过2 years old post中的解决方案,但无济于事。

那么如何扩展原始类型的数组,例如 Swift 3 中的 Bool?

只需扩展 Collection 或 Sequence

extension Collection where Element == Bool { 
    var allTrue: Bool { return !contains(false) }
}

edit/update:

Xcode 10 • Swift 4 或更高版本

可以使用Swift4或以后的采集方式allSatisfy

let alltrue = [true, true,true, true,true, true].allSatisfy{[=11=]}  // true

let allfalse = [false, false,false, false,false, false].allSatisfy{![=11=]} // true

extension Collection where Element == Bool {
    var allTrue: Bool { return allSatisfy{ [=12=] } }
    var allFalse: Bool { return allSatisfy{ ![=12=] } }
}

测试场:

[true, true, true, true, true, true].allTrue // true
[false, false, false, false, false, false].allFalse // true

Apple 在 Swift 3.0 (see Apple's Swift source code on GitHub) 中将 _ArrayType 替换为 _ArrayProtocol,因此您可以执行与 Swift 2.2 中相同的操作以下:

extension _ArrayProtocol where Iterator.Element == Bool {
    var allTrue : Bool { return !self.contains(false) }
}

扩展 _ArrayProtocolCollection 对我没用,但 Sequence 对我有用。

public extension Sequence where Iterator.Element == String
{
    var allTrue: Bool { return !contains(false)
}

从 Swift 3.1 开始(包含在 Xcode 8.3 中),您现在可以 extend a type with a concrete constraint:

extension Array where Element == Bool {
    var allTrue: Bool {
        return !contains(false)
    }
}

您也可以扩展 Collection 而不是 Array,但您需要限制 Iterator.Element,而不仅仅是 Element