Swift中String未显式遵守RawRepresentable为何可做枚举原始值?
Swift枚举原始值机制说明
- 你观察到的差异是Swift编译器对内置类型和自定义类型的差异化处理导致的,你的判断是正确的:
String属于标准库内置基础类型,编译器会对这类类型提供枚举原始值的隐式支持,自定义类型则需要手动实现相关逻辑。 - 内置类型(
String/Int/Double/Bool等)作为枚举原始值时的逻辑:- 这类场景的支持是编译器级别的语法糖,不会写在标准库的公开源码中,所以你在
String的源码里找不到rawValue相关声明是正常的。 - 当你声明
enum Test1: String这类枚举时,编译器会自动为枚举合成RawRepresentable协议的完整实现:自动生成rawValue属性、init?(rawValue: String)可失败构造器,没有手动赋值的case会自动用case名作为对应的字符串原始值。
- 这类场景的支持是编译器级别的语法糖,不会写在标准库的公开源码中,所以你在
- 自定义类型作为枚举原始值的要求:
- 编译器不会为自定义类型的原始值枚举自动合成
RawRepresentable实现,所以你不能直接用enum Test2: MyStruct的写法声明,需要手动实现RawRepresentable协议的所有要求。 - 自定义类型本身需要先遵守
Equatable协议,你的代码中这部分已经实现。
- 编译器不会为自定义类型的原始值枚举自动合成
以下是可正常运行的修正代码示例:
struct MyStruct: Equatable { let id: String } enum Test2 { case value } // 显式实现RawRepresentable协议 extension Test2: RawRepresentable { typealias RawValue = MyStruct var rawValue: MyStruct { switch self { case .value: return MyStruct(id: "value") } } init?(rawValue: MyStruct) { if rawValue.id == "value" { self = .value } else { return nil } } } // 测试调用 let test2 = Test2.value.rawValue
内容的提问来源于stack exchange,提问作者user14205680
相关产品推荐
相关产品推荐

