【发布时间】:2018-09-27 17:34:52
【问题描述】:
考虑这个枚举...
enum ServiceValue : String, Decodable {
case a
case b
case c
case other
}
给定一个字符串'a',你可以获得一个枚举实例,如下所示:
// 'value' is an optional since the initializer is bailable
let value = ServiceValue(rawValue:'a')
我们想要做的不是为未知值(例如“d”或“somethingUnknown”)返回“nil”,而是要返回ServiceValue.other。但是,您不能覆盖初始化程序,因为它不在基类中,而是编译器为此枚举本身生成的。
也就是说,我们尝试自己滚动,就像这样......
init(serviceValue:String){
self.init(rawValue:serviceValue) ?? self.init(rawValue:"other")
}
...但这不适用于以下错误:
一个不可失败的初始化器不能委托给用“init?”编写的可失败的初始化器“init(rawValue:)”
和
初始化器委托('self.init')不能嵌套在另一个表达式中
当然我可以简单地写一个静态方法initFrom,像这样……
initFrom(serviceValue:String) -> ServiceValue {
return ServiceValue(rawValue:serviceValue) ?? ServiceValue(rawValue:"other")
}
...但这是一个工厂方法,不是真正的初始化程序,也不能防止仍在使用init(rawValue: 的人(尽管最后一部分可能很好,因为它会改变预期的行为。在一个完美的世界中,我'会完全隐藏该初始化程序,但同样,您不能在枚举中覆盖初始化程序。)
那么这可以实现吗,还是工厂模式是唯一的出路?
【问题讨论】:
-
init(string: String) { self = ServiceValue(rawValue: string) ?? .other } -
除非我误解了某些东西,否则我不确定这是否相同,因为那是关于在对象上初始化 properties 的。在枚举的情况下,它是我试图默认的对象 itself。 (我希望我能看到编译器生成的内容,以便我可以复制它,仍然是一个 init,但具有不同的签名。)
-
Leo,你能把它放在答案中吗?
标签: swift enums swift4 failable