Swift泛型类型扩展出现Invalid redeclaration编译错误咨询
为什么Dictionary的不同扩展中,静态函数和静态属性同名会报重定义错误?
这个问题的核心在于Swift对类型成员的命名空间规则,以及扩展约束的生效时机。让我一步步拆解:
1. 存储属性和函数共享同一命名空间
在Swift中,类型的静态存储属性和静态函数属于同一个命名空间——也就是说,它们的名字不能重复,哪怕是在不同的扩展里、带有不同的泛型约束。
当你写:
// 第一个扩展:静态函数foo extension Dictionary where Key == String, Value == String { static func foo() -> [String: String] { return [ "bar": "bar", "baz": "baz" ] } } // 第二个扩展:静态存储属性foo extension Dictionary where Key == String, Value == Int { static let foo: [String: Int] = [ "bar": 0, "baz": 1 ] }
编译器看到的是:Dictionary类型有两个名为foo的静态成员——一个是函数,一个是存储属性。不管它们的泛型约束如何,名字冲突就是冲突,所以抛出Invalid redeclaration of 'foo'错误。
2. 同类型成员(都是函数/都是属性)为什么能通过?
当两个扩展里的foo都是静态函数时:
extension Dictionary where Key == String, Value == String { static func foo() -> [String: String] { return [ "bar": "bar", "baz": "baz" ] } } extension Dictionary where Key == String, Value == Int { static func foo() -> [String: Int] { return [ "bar": 0, "baz": 1 ] } }
虽然函数名字相同,但它们的泛型约束不同,而且Swift会在调用时根据上下文推断应该使用哪个版本:
- 当你写
let strDict: [String: String] = Dictionary.foo(),编译器会匹配第一个扩展的函数; - 当你写
let intDict: [String: Int] = Dictionary.foo(),则匹配第二个。
同理,当两个foo都是静态存储属性时:
extension Dictionary where Key == String, Value == String { static let foo: [String: String] = [ "bar": "bar", "baz": "baz" ] } extension Dictionary where Key == String, Value == Int { static let foo: [String: Int] = [ "bar": 0, "baz": 1 ] }
它们的类型不同,且约束不同,编译器在访问时能通过上下文(比如你赋值的变量类型)确定要取哪个扩展的属性,所以不会报错。
3. 本质原因:Swift的名字解析优先级
Swift在处理类型成员的定义时,首先检查名字是否重复,而不会先考虑泛型约束——约束是在调用/访问阶段才会用来筛选合适的成员。所以,只要名字相同,不管是函数还是属性,都会被视为重定义;但如果是同类型的成员(都是函数或都是属性),即使名字相同,只要约束不同,编译器可以在使用阶段区分开,就允许共存。
内容的提问来源于stack exchange,提问作者Broco
相关产品推荐
相关产品推荐

