gpt4 book ai didi

arrays - 使自定义类型符合仅具有下标的 RandomAccessCollection

转载 作者:行者123 更新时间:2023-12-05 04:58:01 25 4
gpt4 key购买 nike

我通常实现行为类似于数组的类型,例如:

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)要求(startIndexendIndex , 表单索引)
  • 完成剩余要求的下标

这种机制类似于目前在 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com