问题描述
我通常实现的行为类似于数组,就像这样:
struct Dataset: RandomAccessCollection {
let ids: [Int]
// Other properties and methods...
// Boilerplate
var startIndex: Int { ids.startIndex }
var endIndex: Int { ids.endIndex }
func formIndex(after i: inout Int) { i + 1 }
func formIndex(before i: inout Int) { i - 1 }
subscript(index: Int) -> Int {
// Dummy example,could be more complex and return a different type
return ids[index]
}
}
问题是我需要为RandomAccessCollection
一致性编写很多样板代码。我想要一种协议或一种机制,将样板减少到仅一个或两个要求:
- 从中推断协议要求(
RandomAccessCollection
,ids
,startIndex
)的基础endIndex
(如我的示例中的formIndex
属性) - 可以满足剩余要求的下标
该机制类似于当前在Pytorch中完成数据集继承的方式:仅具有__len__
和__getitem__
的要求。
我想出了这样的草稿:
protocol ArrayProtocol: RandomAccessCollection where Index == BaseCollection.Index {
associatedtype BaseCollection: RandomAccessCollection
var baseCollection: BaseCollection { get set }
subscript(index: Index) -> Element { get set }
}
// Provide the default implementation of the RandomAccessCollection protocol
extension ArrayProtocol {
var startIndex: Index { baseCollection.startIndex }
var endIndex: Index { baseCollection.endIndex }
func formIndex(after i: inout Index) { baseCollection.index(after: i) }
func formIndex(before i: inout Index) { baseCollection.index(before: i) }
}
该协议将这样使用:
struct Dataset: ArrayProtocol {
let ids: [Int]
// Other properties and methods...
// No more boilerplate
var baseCollection: [Int] { ids }
subscript(index: Int) -> Int {
// Dummy example,could be more complex and return a different type
return ids[index]
}
}
但是我找不到使它正常工作的方法,我觉得关联的类型不是很好的设计模式。
有什么办法解决这个问题吗?
编辑:where Index == BaseCollection.Index
子句不是必需的,下标可以具有与基础集合不同的Index
类型。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)