Swift中switch语句下元组字面量匹配Pair编译失败问题
Swift中Switch语句匹配Pair结构体的疑问
我定义了如下泛型结构体:
struct Pair<First, Second> { var first: First var second: Second static func ~= (pattern: (First, Second), value: Pair) -> Bool { /* 自定义匹配逻辑 */ } }
测试代码如下:
func test() { let tuple = (0, "zero") let pair = Pair(0, "zero") (0, "zero") ~= pair tuple ~= pair switch pair { case tuple: return case (0, "zero"): return // 只有这一行报错 // 错误提示:tuple pattern cannot match values of the non-tuple type 'Pair<Int, String>' default: return } }
直接调用~=运算符时,元组字面量和元组实例与Pair的匹配都正常,但在switch语句中,使用元组字面量匹配Pair会报错,这是Bug还是switch语句的特殊规则?
解答
这不是Bug,而是Swift模式匹配系统的特殊规则,核心原因在于switch语句对字面量模式的处理优先级高于自定义~=运算符:
直接调用
~=时的逻辑:
当你直接写(0, "zero") ~= pair,Swift会优先查找符合(First, Second)和Pair类型的自定义~=实现,所以能正确调用你定义的静态方法,匹配正常。switch语句中的模式解析逻辑:
在switch的case分支里,Swift会先把(0, "zero")解析成元组字面量模式,而不是把它当作一个(Int, String)类型的实例来匹配你的自定义~=方法。元组字面量模式只能匹配元组类型的值,而Pair<Int, String>不是元组,因此触发类型不匹配的错误。而
case tuple:能正常工作,是因为tuple是一个已声明的元组实例,Swift会把它解析成表达式模式,此时才会去查找对应的自定义~=运算符实现,从而完成匹配。
如果想让元组字面量在switch中也能匹配Pair,可以通过以下方式解决:
- 把元组字面量包裹在括号里,强制Swift将其解析为表达式模式:
case ((0, "zero")): return - 自定义适配元组字面量的模式类型,或者为Pair添加更贴合的模式匹配支持。
内容的提问来源于stack exchange,提问作者funct7
相关产品推荐
相关产品推荐

