- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我通常实现行为类似于数组的类型,例如:
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
一致性编写大量样板代码。我想要一个协议(protocol)或机制将样板减少到只有一个或两个要求:
RandomAccessCollection
(如我示例中的 ids
属性),从中推断协议(protocol)要求(startIndex
、endIndex
, 表单索引
)这种机制类似于目前在 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) }
}
这个协议(protocol)可以这样使用:
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 }
}
关于arrays - 使自定义类型符合仅具有下标的 RandomAccessCollection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64142584/
我通常实现行为类似于数组的类型,例如: struct Dataset: RandomAccessCollection { let ids: [Int] // Other propert
我有一个协议(protocol),我想表达一个函数/变量可以返回一个特定类型的 RandomAccessCollection - 不一定是一个 Array 因为对于一个实现它使用访问数据的库。将库调用
根据 Swift 5 文档,String 的方法 randomElement() 复杂度为 O(1) 或 O(*n*) 取决于符合 RandomAccessCollection 协议(protocol
当我们尝试从 Array 中检索一系列元素时,我们会返回一个 ArraySlice: let array = [1, 3, 5, 2] let arraySlice = array[..(_ c: T
使用 _base 属性访问 ReverseRandomAccessCollection 的元素是一种好习惯吗? let myArray = [1, 2, 3] print(myArray.first)
我是一名优秀的程序员,十分优秀!