2016-09-22 13 views
11

Trước đây trong Swift 2.2 Tôi có thể làm:Mở rộng các mảng đã nhập (của các kiểu nguyên thủy như Bool) trong Swift 3?

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

kéo dài [Bool] với .allTrue. Ví dụ.

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

Nhưng trong Swift 3.0 Tôi nhận được lỗi này:

undeclared type _ArrayType


Vì vậy, tôi đã cố gắng chuyển đổi nó để Array và sử dụng các từ khóa mới Iterator

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

Nhưng tôi có một lỗi khác phàn nàn rằng tôi đang buộc phần tử không phải là chung chung

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


Tôi cũng đã thử các giải pháp trong 2 years old post này nhưng không có kết quả.

Vậy làm cách nào để mở rộng mảng các kiểu nguyên thủy như Bool trong Swift 3?

+0

liên quan: http://stackoverflow.com/questions/31806324/extend-array-types-using-where-clause-in-swift –

Trả lời

8

Chỉ cần mở rộng bộ sưu tập hoặc trình tự

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

Testing Playground:

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

Một lựa chọn khác là tạo ra một giao thức tùy chỉnh và mở rộng nó:

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

Apple thay thế _ArrayType với _ArrayProtocol trong Swift 3.0 (see Apple's Swift source code on GitHub) để bạn có thể làm điều tương tự bạn đã làm trong Swift 2.2 bằng cách làm như sau:

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

Điều này gần như chính xác, Nếu bạn mở rộng _ArrayProtocol, bạn sẽ cần phải hạn chế nó 'ở đâu Iterator.Element == Bool' –

+0

Cảm ơn thông tin. Rất thú vị. Tôi gần như quên nó là nguồn mở. –

+0

Không vấn đề gì, tôi đã gặp một vấn đề tương tự (ngoài một số khác) di chuyển từ Swift 2 đến 3 và tìm kiếm thông qua mã nguồn không thể bị tổn thươ[email protected] bất kỳ cơ hội nào bạn có thể giải thích tại sao bạn cần phải hạn chế '_ArrayProtocol' với' nơi Iterator.Element == Bool' như trái ngược với 'where Element == Bool'? –

0

Mở rộng _ArrayProtocol hoặc Collection không làm việc cho tôi nhưng Sequence đã làm.

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

Tính Swift 3.1 (bao gồm trong Xcode 8.3), bạn có thể bây giờ extend a type with a concrete constraint:

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

Bạn cũng có thể mở rộng Collection thay vì Array, nhưng bạn sẽ cần phải hạn chế Iterator.Element, không chỉ Element.

+0

Bạn có thể khái quát hơn nữa, với phần mở rộng trên 'Chuỗi ' – Alexander

Các vấn đề liên quan