arrays - 扩展集合:数组和集合,但不是字典
问题描述
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
s 和Set
s 的初始化程序实际上可以添加到 all Sequences
,因为您没有使用Array
or中唯一的任何内容Set
。初始化程序所依赖的所有内容是:
- 具有
Element
关联类型 - 有一个初始化器,它需要一个
Sequence
Sequence
Array
满足第一个标准,并且两者之间没有Set
满足第二个标准的通用协议:-(。来自的一个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
和init
。
关于编写扩展的提示:尝试找到你的扩展所依赖/需要的所有东西,然后找到包含所有这些东西的最通用类型。那是你应该写扩展的类型。
推荐阅读
- amazon-web-services - Aws acm - 由于证书颁发机构身份验证 (CAA) 错误,一个或多个域名验证失败
- java - Spring Data JPA 更新查询(不支持 DML 操作)
- python-turtle - 为什么 docs.python.org 中的“海龟之星”不起作用?
- mono.cecil - 在 Mono.Cecil 中是否可以确定调用方法的对象的实际类型?
- django - 尝试使用基于类的视图迭代 Django 中的模型,但得到错误 Project object is not iterable
- sql - 用逗号将多行合并为一行
- angular - 异步管道引用导致无限循环
- java - 尝试在 Eclipse 中设置调试配置时未显示项目
- javascript - 将 Vue v2 代码移植到 v3。与 V3 中类似的 _b _t 编译器命令是什么?
- flutter - 无法在颤振文件选择器上获取真实位置