【发布时间】:2015-02-08 01:20:52
【问题描述】:
我已尝试通过以下方式将此问题归结为最简单的形式。
设置
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?'
注意事项
-
如果您使用原始值类型定义枚举,则该枚举会自动接收一个初始值设定项,该初始化程序采用原始值类型的值(作为称为
rawValue的参数)并返回枚举成员或nil。 -
MyEnum的自定义初始值设定项在扩展中定义,以测试枚举的原始值初始值设定项是否因为来自the Language Guide 的以下情况而被删除。但是,它实现了相同的错误结果。请注意,如果您为值类型定义自定义初始化程序,您将无法再访问该类型的默认初始化程序(或成员初始化程序,如果它是结构)。 [...]
如果您希望自定义值类型可以使用默认初始化程序和成员初始化程序以及您自己的自定义初始化程序进行初始化,请将自定义初始化程序编写在扩展中,而不是作为值类型原始实现的一部分。 将枚举定义移动到
MyClass.swift可以解决bar的错误,但不能解决foo的错误。删除自定义初始化程序可以解决这两个错误。
-
一种解决方法是在枚举定义中包含以下函数,并使用它来代替提供的原始值初始值设定项。因此,添加自定义初始化程序似乎与标记原始值初始化程序
private具有类似的效果。init?(raw: Int) { self.init(rawValue: raw) } -
在
MyClass.swift中显式声明协议符合RawRepresentable可解决bar的内联错误,但会导致有关重复符号的链接器错误(因为原始值类型枚举隐式符合RawRepresentable)。extension MyEnum: RawRepresentable {}
谁能提供更多关于这里发生的事情的见解?为什么原始值初始化器不可访问?
【问题讨论】:
-
你应该提交一个错误 - 默认初始化程序应该有
internal范围(或至少匹配类型),而不是private。 -
我遇到了完全相同的问题。一旦我创建了一个自定义初始化程序,默认初始化程序就消失了
-
我闻起来像个虫子。
-
感谢您验证我的怀疑。这已作为错误提交。
-
5 号为我做了。