如何解决扩展集合:数组和集合,但不扩展字典
extension Array {
init?<S: Sequence>(_ sequence: S?) where S.Element == Element {
guard let sequence = sequence else { return nil }
self.init(sequence)
}
}
extension Set {
init?<S: Sequence>(_ sequence: S?) where S.Element == Element {
guard let sequence = sequence else { return nil }
self.init(sequence)
}
}
如您所见,两个扩展中的代码是完全相同的。那么,如何在不重复的情况下重写它呢?像这样:
extension Collection where type == Array || type == Set {
init?<S: Sequence>(_ sequence: S?) where S.Element == Element {
guard let sequence = sequence else { return nil }
self.init(sequence)
}
}
解决方法
实际上,您要添加到Array
和Set
的初始化程序可以添加到所有Sequences
,因为您没有使用{{1} }或Array
。初始化程序所依赖的全部是:
- 具有
Set
关联类型 - 具有一个初始化器,该初始化器需要一个
Element
Sequence
满足第一个条件,并且Sequence
和Array
之间没有满足第二个条件的通用协议:-(。Set
中的一个协议来自{ {3}}。来自Array
的一个来自RangeReplaceableCollection
。
您可以自己创建这样的协议:
Set
或者(SetAlgebra
),如果您不介意写protocol SequenceInitialisable : Sequence {
init<S: Sequence>(_ s: S) where S.Element == Element
}
extension Array : SequenceInitialisable {}
extension Set : SequenceInitialisable {}
extension SequenceInitialisable {
init?<S: Sequence>(_ sequence: S?) where S.Element == Element {
guard let sequence = sequence else { return nil }
self.init(sequence)
}
}
和sequence.map(Array.init)
,也可以只做map
。
编写扩展的提示:尝试查找扩展所依赖/需要的所有内容,然后找到具有所有这些内容的最通用的类型。那是您应该在其中编写扩展名的类型。
,您可以执行以下操作:
protocol NilSequenceInitializable {}
extension NilSequenceInitializable where Self: Sequence {
init?<S: Sequence>(_ sequence: S?) where S.Element == Element {
guard let sequence = sequence else { return nil }
self.init(sequence)
}
}
extension Array: NilSequenceInitializable {}
extension Set: NilSequenceInitializable {}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。