Swift泛型函数调用报错:无法使用指定参数列表调用load(groceries:)
解决Swift泛型函数中关联类型的约束匹配问题
你遇到的问题核心在于类型等式约束的严格匹配要求:你的load函数要求GroceriesQuery.Groceries必须完全等于[Vegetable],但CucumberQuery的关联类型是[Cucumber]——虽然Cucumber遵循Vegetable,但[Cucumber]和[Vegetable]是Swift中的两个不同类型,所以不满足==的约束条件,导致调用失败。
修正方案:约束关联类型的元素类型
我们不需要严格要求关联类型是[Vegetable],而是可以约束关联类型的元素遵循Vegetable协议。修改后的代码如下:
protocol Query { associatedtype Groceries } class CucumberQuery: Query { typealias Groceries = [Cucumber] } protocol Vegetable { } struct Cucumber: Vegetable { } // 修改函数的where约束,检查Groceries的Element是否遵循Vegetable func load<GroceriesQuery: Query>(groceries: GroceriesQuery) where GroceriesQuery.Groceries: Sequence, GroceriesQuery.Groceries.Element: Vegetable { } load(groceries: CucumberQuery()) // 现在可以正常调用了
补充优化方案
如果你的Groceries关联类型本来就应该是数组类型,也可以更精准地约束:
func load<GroceriesQuery: Query>(groceries: GroceriesQuery) where GroceriesQuery.Groceries == [some Vegetable] { }
或者在协议层面就给关联类型添加约束,让后续的实现更符合预期,同时简化函数定义:
protocol Query { associatedtype Groceries: Sequence where Groceries.Element: Vegetable } class CucumberQuery: Query { typealias Groceries = [Cucumber] } // 此时函数无需额外约束 func load<GroceriesQuery: Query>(groceries: GroceriesQuery) { } load(groceries: CucumberQuery())
这样调整后,既保留了对关联类型的约束,又允许具体类型(比如[Cucumber])满足要求,因为我们关注的是元素是否符合协议,而不是数组类型的完全匹配。
内容的提问来源于stack exchange,提问作者Balázs Vincze
相关产品推荐
相关产品推荐

