gpt4 book ai didi

swift - 为什么我的 Swift 协议(protocol)扩展不能包装相同类型的现有函数?

转载 作者:搜寻专家 更新时间:2023-10-31 08:31:39 24 4
gpt4 key购买 nike

我正在尝试为一个集合创建一个“安全”的下标运算符——一个忽略超出集合可用索引范围的部分的运算符。

期望的行为是在所有情况下都返回一个 Slice;当下标范围与集合范围不重叠时,应返回空数组。

这似乎是对 this answer 中介绍的技术的直接扩展. documentation of the collection subscript operator is very straightforward :

subscript(bounds: Range<Self.Index>) -> Slice<Self> { get }

但是当我在我的包装函数中采用这些相同的类型时,我得到以下信息: snippet

复制/粘贴版本:

extension Collection where Indices.Iterator.Element == Index {
subscript(safe bounds: Range<Self.Index>) -> Slice<Self> {
let empty = Slice(base: self, bounds: (startIndex..<startIndex))
guard bounds.lowerBound < endIndex else { return empty }
guard bounds.upperBound >= startIndex else { return empty }

let lo = Swift.max(startIndex, bounds.lowerBound)
let hi = Swift.min(endIndex, bounds.upperBound)
return self[lo..<hi]
}
}

为什么我不能用这种方式下标一个集合?为什么编译器确认我使用的是正确类型的 Range<Self.Index> (在文档中指定)但仍然认为这是一个错误?

最佳答案

The ranged subscript requirement of Collection 返回 SubSequence (关联类型):

subscript(bounds: Range<Self.Index>) -> Self.SubSequence { get }

subscript that you refer to :

subscript(bounds: Range<Self.Index>) -> Slice<Self> { get }

只是该下标的默认实现,其中 SubSequenceSlice<Self> .任何符合 Collection 的类型可以以不同的方式实现此要求——他们不一定需要定义自己的 SubSequence成为Slice<Self> .

因此,您只需更改您的扩展名以反射(reflect) SubSequence从您使用的下标返回:

extension Collection {
subscript(safe bounds: Range<Index>) -> SubSequence {

// as the method returns a SubSequence,
// use the regular subscript to get an empty SubSequence
let empty = self[startIndex..<startIndex]

guard bounds.lowerBound < endIndex else { return empty }
guard bounds.upperBound >= startIndex else { return empty }

let lo = Swift.max(startIndex, bounds.lowerBound)
let hi = Swift.min(endIndex, bounds.upperBound)

return self[lo..<hi]
}
}

关于swift - 为什么我的 Swift 协议(protocol)扩展不能包装相同类型的现有函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41044599/

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