建立
Xcode版本6.1.1(6A2008a)
在MyEnum.swift中定义的枚举:
internal enum MyEnum: Int { case Zero = 0,One,Two } extension MyEnum { init?(string: String) { switch string.lowercaseString { case "zero": self = .Zero case "one": self = .One case "two": self = .Two default: return nil } } }
和在另一个文件MyClass.swift中初始化枚举的代码:
internal class MyClass { let foo = MyEnum(rawValue: 0) // Error let fooStr = MyEnum(string: "zero") func testFunc() { let bar = MyEnum(rawValue: 1) // Error let barStr = MyEnum(string: "one") } }
Xcode在尝试使用其原始值初始值设置初始化MyEnum时给出以下错误:
Cannot convert the expression's type '(rawValue: IntegerLiteralConvertible)' to type 'MyEnum?'
笔记
If you define an enumeration with a raw-value type,the enumeration automatically receives an initializer that takes a value of the raw value’s type (as a parameter called
rawValue
) and returns either an enumeration member ornil
.
> MyEnum的自定义初始化程序在扩展中定义,用于测试枚举的原始值初始值程序是否正在从the Language Guide的下列情况中删除。但是,它实现了相同的错误结果。
Note that if you define a custom initializer for a value type,you will no longer have access to the default initializer (or the memberwise initializer,if it is a structure) for that type. […]
If you want your custom value type to be initializable with the default initializer and memberwise initializer,and also with your own custom initializers,write your custom initializers in an extension rather than as part of the value type’s original implementation.
>将枚举定义移动到MyClass.swift解析bar的错误,但不解析foo的错误。
>删除自定义初始值设置器可以解决这两个错误。
>一种解决方法是在枚举定义中包含以下函数,并使用它来代替提供的原始值初始值。所以看起来像添加一个自定义初始化器具有类似的效果,标记原始值初始化器私有。
init?(raw: Int) { self.init(rawValue: raw) }
>在MyClass.swift中明确声明与RawRepresentable的协议一致性解决了bar的内联错误,但会导致关于重复符号的链接器错误(因为原始值类型枚举隐式符合RawRepresentable)。
extension MyEnum: RawRepresentable {}
任何人都可以提供更多的洞察这里发生了什么?为什么不能访问原始值初始化程序?