Swift中Request协议为何能自动推断Parameter类型?多空参数类型时为何报错?
为什么编译器能自动推断Parameter类型为NeverParameter?
Swift协议的关联类型推断有个规则:当协议存在唯一的协议扩展,能为关联类型提供符合约束要求的默认实现时,编译器会自动把这个扩展里的类型作为关联类型的默认值。
你只定义了NeverParameter这一个空参数类型,并且给Request协议编写了对应扩展,提供了var parameter: NeverParameter? = nil的默认实现。此时编译器找不到其他符合RequestParameter约束的候选类型,所以会自动帮FooRequest推断出Parameter = NeverParameter,不需要你显式声明typealias Parameter = NeverParameter。
添加NeverParameter1后报错的原因是什么?
新增NeverParameter1及对应协议扩展后,现在有两个不同类型(NeverParameter和NeverParameter1)都满足RequestParameter约束,且各自有对应的Request协议扩展提供parameter的默认实现。
这时候编译器陷入了歧义:它无法确定FooRequest的Parameter关联类型该选哪一个。因为没有明确的指令(比如显式声明typealias),编译器无法自动做出选择,所以会抛出“Type 'FooRequest' does not conform to protocol 'Request'”的错误——本质是关联类型的推断出现了多候选冲突。
解决方法很直接:给FooRequest显式声明typealias Parameter = NeverParameter(或者你需要的那个类型),明确指定关联类型即可。
内容的提问来源于stack exchange,提问作者shinolr

