【问题标题】:Extending typed Arrays (of primitive types like Bool) in Swift 3?在 Swift 3 中扩展类型化数组(原始类型如 Bool)?
【发布时间】:2016-09-22 01:02:48
【问题描述】:

以前在 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 years old post 中的解决方案,但无济于事。

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

【问题讨论】:

标签: arrays swift extension-methods swift3


【解决方案1】:

只需扩展集合或序列

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

编辑/更新:

Xcode 10 • Swift 4 或更高版本

您可以使用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 } }
}

测试操场:

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

【讨论】:

    【解决方案2】:

    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) }
    }
    

    【讨论】:

    • 这几乎是正确的,如果你扩展 _ArrayProtocol 你需要约束它where Iterator.Element == Bool
    • 感谢您的信息。很有意思。我差点忘了它是开源的。
    • 没问题,我在从 Swift 2 迁移到 3 时遇到了类似的问题(除了其他几个问题),并且认为查看源代码不会有什么坏处。 @LeoDabus 任何机会你都可以解释为什么你需要用where Iterator.Element == Bool 来限制_ArrayProtocol 而不是where Element == Bool
    • 这对我不起作用。 Use of undeclared type _ArrayProtocol
    • 是的。扩展集合也不起作用,但扩展序列可以。
    【解决方案3】:

    从 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

    【讨论】:

    • 您可以将其进一步概括为Sequence上的扩展
    【解决方案4】:

    扩展_ArrayProtocolCollection 对我不起作用,但Sequence 起作用。

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

    【讨论】:

      猜你喜欢
      • 2014-07-24
      • 1970-01-01
      • 2014-06-11
      • 1970-01-01
      • 2022-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多