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

天大地大妈咪最大 提交于 2019-12-04 17:37:46

问题


Previously in Swift 2.2 I'm able to do:

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

which extends [Bool] with .allTrue. E.g.

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

But in Swift 3.0 I'm getting this error:

undeclared type _ArrayType


So I tried switching it to Array and using the new keyword Iterator

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

But I got a different error complaining that I'm forcing element to be non-generic

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


I've also tried the solutions in this 2 years old post but to no avail.

So how does one extend arrays of primitive types like Bool in Swift 3?


回答1:


Just extend the Collection or the Sequence

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

edit/update:

Xcode 10 • Swift 4 or later

You can use Swift 4 or later collection method allSatisfy

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

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

extension Collection where Element == Bool {
    var allTrue: Bool { return allSatisfy{ $0 } }
    var allFalse: Bool { return allSatisfy{ !$0 } }
}

Testing Playground:

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



回答2:


Apple replaced _ArrayType with _ArrayProtocol in Swift 3.0 (see Apple's Swift source code on GitHub) so you can do the same thing you did in Swift 2.2 by doing the following:

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



回答3:


As of Swift 3.1 (included in Xcode 8.3), you can now extend a type with a concrete constraint:

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

You can also extend Collection instead of Array, but you'll need to constrain Iterator.Element, not just Element.




回答4:


Extending _ArrayProtocol or Collection didn't work for me but Sequence did.

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


来源:https://stackoverflow.com/questions/39628695/extending-typed-arrays-of-primitive-types-like-bool-in-swift-3

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!