ios 覆盖 Enum init?(rawValue: String) 不是可选的
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35119647/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Overriding Enum init?(rawValue: String) to not be optional
提问by Prettygeek
I want to have init from rawValue for my enum in Swift to return default value if rawValue init will return nil. Right now I have something like this:
如果 rawValue init 将返回 nil,我想在 Swift 中为我的枚举从 rawValue init 返回默认值。现在我有这样的事情:
public init(fromRawValue: String){
self = Language(rawValue: fromRawValue) ?? .English
}
I don't like this because it is completely new initializer. I tried to make something like this:
我不喜欢这个,因为它是全新的初始化程序。我试图做这样的事情:
public init(rawValue: String){
self = Language(rawValue: fromRawValue) ?? .English
}
But I have got runtime exception with bad access. Can I somehow make it work or I just have to use this new and I cannot override original one to not be optional?
但是我遇到了访问错误的运行时异常。我可以以某种方式使它工作,或者我只需要使用这个新的并且我不能覆盖原始的而不是可选的?
I would like to know if it possible to override original init from rawValue not workaround with completely new one that is using failable one.
我想知道是否有可能从 rawValue 覆盖原始 init 而不是使用可失败的全新的解决方法。
回答by Luca Angeletti
The default initializer is failable
. It means that if the received parameter does not match a valid enum case it does return nil
.
默认初始化程序是failable
. 这意味着如果接收到的参数与有效的枚举大小写不匹配,它会返回nil
.
Now you want to do 2 incompatibles things:
现在你想做两件不兼容的事情:
- You want to redefinethe default initializer making it not failable. Infact you want a default enum value created when the received param is not valid.
- Inside your redefined initializer you want to call a failable initializer (which no longer exists) using the same name of the new one.
- 您想重新定义默认初始化程序,使其不会失败。事实上,当接收到的参数无效时,您希望创建一个默认的枚举值。
- 在重新定义的初始化程序中,您希望使用与新初始化程序相同的名称调用可失败初始化程序(不再存在)。
This is not possible, I the 3 possible solutions as follows:
这是不可能的,我提出了以下 3 种可能的解决方案:
1) Creating a different init
1)创建一个不同的init
You define a new not failable initializer with a default value, a different parameter name and inside it you call the default failable initializer.
你定义一个新的不可失败初始化器,它有一个默认值,一个不同的参数名称,在它里面你调用默认的可失败初始化器。
enum Language: String {
case english = "English", italian = "Italian", french = "French"
init(fromRawValue: String){
self = Language(rawValue: fromRawValue) ?? .english
}
}
2) Redefining the default init
2)重新定义默认的init
You redefine the default initializer, you make it not failable and you write the full logic inside it.
您重新定义默认初始化程序,使其不可失败,并在其中编写完整的逻辑。
enum Language: String {
case english = "English", italian = "Italian", french = "French"
init(rawValue: String) {
switch rawValue {
case "Italian": self = .italian
case "French": self = .french
default: self = .english
}
}
}
3) Creating a static func
3) 创建一个静态函数
enum Language: String {
case english = "English", italian = "Italian", french = "French"
static func build(rawValue: String) -> Language {
return Language(rawValue: rawValue) ?? .english
}
}
Now you can build a Language
value writing:
现在你可以建立一个Language
价值写作:
let italian = Language.build(rawValue: "Italian") // Italian
let defaultValue = Language.build(rawValue: "Wrong input") // English
回答by Nathan Hosselton
Adding to Luca's solution for redefining the default init, it is possible to additionally make the rawValue
parameter type optional, which cuts down on some code at the call site when the data source is not reliable.
添加到 Luca 重新定义默认 init 的解决方案中,可以额外使rawValue
参数类型可选,这在数据源不可靠时减少了调用站点的一些代码。
enum PrecipitationType: String {
case rain, snow, sleet, none
typealias RawValue = String
init(rawValue: String?) {
guard let rawValue = rawValue else { self = .none; return }
switch rawValue {
case PrecipitationType.rain.rawValue: self = .rain
case PrecipitationType.snow.rawValue: self = .snow
case PrecipitationType.sleet.rawValue: self = .sleet
default: self = .none
}
}
}
When I initially tried this it generated multiple errors. The key was to redefine the RawValue
typealias to maintain conformance to RawRepresentable
.
当我最初尝试这个时,它产生了多个错误。关键是重新定义类型RawValue
别名以保持与RawRepresentable
.