我已尝试通过以下方法将此问题简化为最简单的形式。
建立
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")
}
}
错误
尝试MyEnum
使用原始值初始化程序进行初始化时,Xcode给我以下错误:
Cannot convert the expression's type '(rawValue: IntegerLiteralConvertible)' to type 'MyEnum?'
笔记
根据《 Swift语言指南》:
如果您使用原始值类型定义枚举,则枚举会自动接收一个初始化器,该初始化器采用原始值类型的值(称为
rawValue
)作为参数,并返回枚举成员或nil
。MyEnum
在扩展程序中定义了的自定义初始化程序,以测试是否由于《语言指南》中的以下情况而删除了枚举的原始值初始化程序。但是,它获得相同的错误结果。请注意,如果您为值类型定义自定义初始化程序,则将不再有权使用该类型的默认初始化程序(或成员初始化程序,如果它是结构)。[...]
如果您希望自定义值类型可以使用默认的初始化器和成员初始化器以及您自己的自定义初始化器进行初始化,请在扩展名中编写自定义初始化器,而不是将其作为值类型的原始实现的一部分。将枚举定义移动到
MyClass.swift
可以解决的错误,bar
但不能解决的错误foo
。删除自定义初始化程序可以解决这两个错误。
一种解决方法是在枚举定义中包括以下功能,并代替提供的原始值初始化程序使用它。因此,似乎添加自定义初始化程序与标记原始值初始化程序具有相似的效果
private
。init?(raw: Int) { self.init(rawValue: raw) }
明确声明
RawRepresentable
in的协议符合性MyClass.swift
可解决的内联错误bar
,但会导致有关重复符号的链接器错误(因为原始值类型枚举隐式符合RawRepresentable
)。extension MyEnum: RawRepresentable {}
任何人都可以对这里发生的事情提供更多的见解吗?为什么无法访问原始值初始化程序?
internal
作用域(或至少与类型匹配),而不是作用域private
。