简体   繁体   English

在Swift 3中扩展类型化的数组(像Bool这样的原始类型)?

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

Previously in Swift 2.2 I'm able to do: 以前在Swift 2.2中我能做到:

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

which extends [Bool] with .allTrue . 它使用.allTrue扩展[Bool] Eg 例如

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

But in Swift 3.0 I'm getting this error: 但是在Swift 3.0中我遇到了这个错误:

undeclared type _ArrayType 未声明的类型_ArrayType


So I tried switching it to Array and using the new keyword Iterator 所以我尝试将其切换到Array并使用新的关键字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 相同类型的要求使通用参数'Element'非通用


I've also tried the solutions in this 2 years old post but to no avail. 我也在这个2年的帖子中尝试了解决方案,但无济于事。

So how does one extend arrays of primitive types like Bool in Swift 3? 那么如何在Swift 3中扩展原始类型的数组,如Bool?

Just extend the Collection or the Sequence 只需扩展Collection或Sequence

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

edit/update: 编辑/更新:

Xcode 10 • Swift 4 or later Xcode 10•Swift 4或更高版本

You can use Swift 4 or later collection method allSatisfy 您可以使用Swift 4或更高版本的收集方法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

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: 苹果取代_ArrayType_ArrayProtocol在雨燕3.0( 见GitHub上苹果的斯威夫特源代码 ),这样你可以做你的雨燕2.2通过执行以下操作做了同样的事情:

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

As of Swift 3.1 (included in Xcode 8.3), you can now extend a type with a concrete constraint : 从Swift 3.1(包含在Xcode 8.3中)开始,您现在可以使用具体约束扩展类型

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 . 您也可以扩展Collection而不是Array ,但是您需要约束Iterator.Element ,而不仅仅是Element

Extending _ArrayProtocol or Collection didn't work for me but Sequence did. 扩展_ArrayProtocolCollection对我来说不起作用,但是Sequence确实如此。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM