Swift的Sequence协议为何无需显式声明Element和Iterator类型别名?
问题原因分析
核心差异是你自定义的MySequence缺少了和标准库Sequence一致的关联类型默认值声明,这是自动推导生效的核心前提。
1. 关联类型约束不等于默认值
你在MySequence中写的associatedtype Element where Self.Element == Self.Iterator.Element只是类型约束,仅规定了Element和Iterator.Element必须为相同类型,并没有告诉编译器「当Iterator类型确定时,Element默认等于Iterator.Element」。
而Swift标准库的Sequence协议,额外通过扩展给Element提供了默认值:
extension Sequence { typealias Element = Iterator.Element }
2. 系统Sequence的自动推导逻辑
标准库Sequence的关联类型自动推导分为两步:
- 第一步:你实现了
makeIterator()方法,返回值是明确的Array<T>.Iterator类型,编译器自动推导出关联类型Iterator = Array<T>.Iterator - 第二步:因为
Element有默认值Iterator.Element,编译器自动用第一步推导出的Iterator的Element类型(也就是泛型T),赋值给Sequence的Element关联类型,两个关联类型都推导完成,不需要手动写typealias。
3. 让你的MySequence支持自动推导的方案
只需要给你的MySequence加一个扩展,声明Element的默认值即可:
public protocol MySequence { associatedtype Element where Self.Element == Self.Iterator.Element associatedtype Iterator : IteratorProtocol func makeIterator() -> Self.Iterator } // 新增这段扩展即可 extension MySequence { typealias Element = Iterator.Element }
添加后你的MultiSet代码不需要做任何修改,编译器就可以自动推导出两个关联类型,不会再报错要求补全存根。
内容的提问来源于stack exchange,提问作者user14205680
相关产品推荐
相关产品推荐

