我试图将这个问题归结为以下最简单的形式。
Xcode Version 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")
}
}
当试图用原始值初始值设定项初始化 MyEnum
时,Xcode 给出了以下错误:
Cannot convert the expression's type '(rawValue: IntegerLiteralConvertible)' to type 'MyEnum?'
每间 快速语言指南:
如果使用原始值类型定义枚举,枚举将自动接收初始值设定项,该初始值设定项接受原始值类型的值(作为名为
rawValue
的参数) ,并返回枚举成员或nil
。
MyEnum
的自定义初始值设定项是在一个扩展中定义的,用于测试枚举的原始值初始值设定项是否因为 语文指引的以下情况而被删除。但是,它得到了相同的错误结果。
请注意,如果为值类型定义自定义初始值设定项,则不再能够访问该类型的默认初始值设定项(或成员方式的初始值设定项,如果它是一个结构)。[...]
如果您希望您的自定义值类型可以使用默认初始值设定项和成员初始值设定项以及您自己的自定义初始值设定项进行初始化,请将您的自定义初始值设定项写入扩展中,而不是作为值类型的原始实现的一部分。
将枚举定义移动到 MyClass.swift
可以解决 bar
的错误,但是 foo
不会。
删除自定义初始值设定项可以解决这两个错误。
一种解决办法是在枚举定义中包含以下函数,并使用它来代替提供的原始值初始值设定项。因此,似乎添加自定义初始值设定项与标记原始值初始值设定项 private
具有类似的效果。
init?(raw: Int) {
self.init(rawValue: raw)
}
Explicitly declaring protocol conformance to RawRepresentable
in MyClass.swift
resolves the inline error for bar
, but results in a linker error about duplicate symbols (because raw-value type enums implicitly conform to RawRepresentable
).
extension MyEnum: RawRepresentable {}
Can anyone provide a little more insight into what's going on here? Why isn't the raw-value initializer accessible?