为什么我必须在我的自定义范围可替换集合中实现 append<S: Sequence>(内容的新元素:S)



我目前正在尝试将自定义集合类型更新到 Swift 4.1。 但是,当我遵守文档并实现CollectionRangeReplaceableCollection的所有要求时,Xcode仍然抱怨我的类型不符合RangeReplaceableCollection

这是问题的MCVE(由Hamish慷慨提供,谢谢你的:)

class Foo<Element : AnyObject> {
required init() {}
private var base: [Element] = []
}
extension Foo : Collection {
typealias Index = Int
var startIndex: Index {
return base.startIndex
}
var endIndex: Index {
return base.endIndex
}
func index(after i: Index) -> Index {
return base.index(after: i)
}
subscript(index: Index) -> Element {
return base[index]
}
}
extension Foo : RangeReplaceableCollection {
func replaceSubrange<C : Collection>(
_ subrange: Range<Index>, with newElements: C
) where Element == C.Element {}
}

根据文档,代码应编译:

将范围可替换集合一致性添加到自定义 集合,添加一个空的初始值设定项和替换子范围(_:with:) 方法到您的自定义类型。范围可替换集合提供 使用它的所有其他方法的默认实现 初始值设定项和方法。

不幸的是,它没有。相反,Xcode 会发出以下错误消息:

// error: type 'Foo<Element>' does not conform to protocol 'RangeReplaceableCollection'
// extension Foo : RangeReplaceableCollection {
// ^
//   Swift.RangeReplaceableCollection:5:26: note: candidate has non-matching type '<Self, S> (contentsOf: S) -> ()' [with SubSequence = Foo<Element>.SubSequence]
//   public mutating func append<S>(contentsOf newElements: S) where S : Sequence, Self.Element == S.Element
//                        ^
//   Swift.RangeReplaceableCollection:9:26: note: protocol requires function 'append(contentsOf:)' with type '<S> (contentsOf: S) -> ()'; do you want to add a stub?
//   public mutating func append<S>(contentsOf newElements: S) where S : Sequence, Self.Element == S.Element
//   

为了确保它不是文档中的错误,我检查了 Swift 4.1 的源代码,并在 RangeReplaceableCollection.swift 第 442-452 行中找到了func append<S>(contentsOf newElements: S) where S: Sequence, Element == S.Element的默认实现:

@_inlineable
public mutating func append<S : Sequence>(contentsOf newElements: S) where S.Element == Element {
let approximateCapacity = self.count + numericCast(newElements.underestimatedCount)
self.reserveCapacity(approximateCapacity)
for element in newElements {
append(element)
}
}

问题:

  • 为什么 Xcode 要求实现此函数,尽管提供了默认实现?
  • 如何编译我的代码?

为什么 Xcode 要求实现这个函数,尽管提供了默认的实现?

这是由于 Swift 4.1
中引入的 TypeChecker 中的一个错误:[SR-7429]:无法使非最终类符合具有默认要求的协议,泛型占位符被约束为关联类型

如何编译我的代码?

在修复错误之前,目前有三种方法可以编译它。

  • 实现以下两个功能:

    • required init<S : Sequence>(_ elements: S) where Element == S.Element {}
    • func append<S : Sequence>(contentsOf newElements: S) where Element == S.Element
  • 将类标记为final

  • 将集合类型实现为struct。为此,必须删除required init() {}

最新更新