我正在尝试制作一个通用的Swift函数,该函数接受两个集合并将一个集合的一部分复制到另一个集合的一部分,类似于语义std::copy
和memcpy
in界面条款。但是,我发现自己无法提出正确的通用参数/函数参数来使其工作。
目标是能够像这样调用它,可能省略最后三个参数中的任何一个:
copy(&output, input, offsetA: 0, offsetB: 4, count: 20)
这是我到目前为止所做的:
func copy
<T: CollectionType, U: CollectionType where
T.Generator.Element == U.Generator.Element,
T.Index == Int, T.Index == U.Index,
T.Generator.Element: Equatable>
(inout a: T, b: U, offsetA: Int = 0, offsetB: Int = 0, count: Int? = nil) {
let max = count ?? b.endIndex - b.startIndex - offsetB
for i in 0..<max {
let indA = offsetA + i
let indB = offsetB + i
a[indA] = b[indB]
}
}
但是,我在a[indA] = b[indB]
行上出现此错误:
找不到接受所提供参数的“下标”的重载
这有点令人惊讶,因为几乎相同的通用约束允许我比较元素,这意味着类型应该是正确的,至少。
我错过了什么?否则,是否已经有其他功能在其他地方执行此操作?
答案 0 :(得分:4)
该错误是因为CollectionType
不提供可分配的下标。切换T
以符合MutableCollectionType
,即添加一个。{/ p>
P.S。如果你想让它变得更通用,你可以为T.Index == Int
切换T.Index: RandomAccessIndexType
。这可能需要摆弄max
一点点。
此外,我认为你可以放弃对元素的要求,我不认为你正在使用它。但请记住,如果元素是类,它将是一个浅层副本。
您可能希望查看ExtensibleCollectionType
协议,该协议增加了创建该类型的新空集合以及向其添加新元素的功能,以及RangeReplaceableCollectionType
,这增加了使用其他集合中的值更新集合中的范围(以及删除元素范围,插入新元素等)。