Conform a custom type to RandomAccessCollection with only a subscript(仅使用下标使自定义类型符合RandomAccessCollection)
本文介绍了仅使用下标使自定义类型符合RandomAccessCollection的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我通常实现行为类似数组的类型,如下所示:
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
类型。
推荐答案
关联类型通常用于泛型类型(通常是集合的元素)。向其添加关联的类型typealias BaseCollection = [Int]
并删除Set的下标要求。
protocol ArrayProtocol: RandomAccessCollection where Index == BaseCollection.Index {
associatedtype BaseCollection: RandomAccessCollection
var baseCollection: BaseCollection { get set }
subscript(index: Index) -> Element { get }
}
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 {
typealias BaseCollection = [Int]
var baseCollection: BaseCollection = [ ]
subscript(index: Int) -> Int { baseCollection[index] }
}
请注意,如果要保留设置的要求subscript(index: Index) -> Element { get set }
,还需要确保BaseCollection
也符合MutableCollection
。
subscript(index: Int) -> BaseCollection.Element {
get { baseCollection[index] }
set { baseCollection[index] = newValue }
}
这篇关于仅使用下标使自定义类型符合RandomAccessCollection的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
沃梦达教程
本文标题为:仅使用下标使自定义类型符合RandomAccessCollection
基础教程推荐
猜你喜欢
- 在 gmail 中为 ios 应用程序检索朋友的朋友 2022-01-01
- 当从同一个组件调用时,两个 IBAction 触发的顺序是什么? 2022-01-01
- Kivy Buildozer 无法构建 apk,命令失败:./distribute.sh -m “kivy"d 2022-01-01
- UIWebView 委托方法 shouldStartLoadWithRequest:在 WKWebView 中等效? 2022-01-01
- 如何在 UIImageView 中异步加载图像? 2022-01-01
- 如何在没有IB的情况下将2个按钮添加到右侧的UINavigationbar? 2022-01-01
- 如何在 iPhone 上显示来自 API 的 HTML 文本? 2022-01-01
- android 应用程序已发布,但在 google play 中找不到 2022-01-01
- Android:对话框关闭而不调用关闭 2022-01-01
- 如何让对象对 Cocos2D 中的触摸做出反应? 2022-01-01