重写Enum init?(rawValue:String)不是可选的

Pre*_*eek 47 enums initialization ios swift

如果rawValue init将返回nil,我想从rawValue为init for Swift中的init返回默认值.现在我有这样的事情:

public init(fromRawValue: String){
        self = Language(rawValue: fromRawValue) ?? .English
}
Run Code Online (Sandbox Code Playgroud)

我不喜欢这个,因为它是全新的初始化程序.我试着做这样的事情:

public init(rawValue: String){
        self = Language(rawValue: fromRawValue) ?? .English
}
Run Code Online (Sandbox Code Playgroud)

但我得到运行时异常,访问不当.我可以以某种方式使它工作或我只是必须使用这个新的,我不能覆盖原来的不是可选的?

我想知道是否有可能从rawValue覆盖原始init而不是使用可用的全新的解决方法.

Luc*_*tti 109

默认的初始化程序是failable.这意味着如果接收的参数与有效的枚举情况不匹配,则确实返回nil.

现在你要做2个不兼容的事情:

  1. 您想要重新定义默认初始化程序,使其无法使用.实际上,您希望在收到的参数无效时创建默认枚举值.
  2. 在重新定义的初始化程序中,您希望使用新名称的初始化程序调用可用的初始化程序(不再存在).

这是不可能的,我的3种可能的解决方案如下:

1)创建不同的init

您可以使用默认值,不同的参数名称定义新的不可用的初始化程序,并在其中调用默认的可用初始化程序.

enum Language: String {

    case english = "English", italian = "Italian", french = "French"

    init(fromRawValue: String){
        self = Language(rawValue: fromRawValue) ?? .english
    }
}
Run Code Online (Sandbox Code Playgroud)

2)重新定义默认初始化

您重新定义了默认的初始值设定项,使其不可用,并在其中编写完整的逻辑.

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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

3)创建静态函数

enum Language: String {

    case english = "English", italian = "Italian", french = "French"

    static func build(rawValue: String) -> Language {
        return Language(rawValue: rawValue) ?? .english
    }
}
Run Code Online (Sandbox Code Playgroud)

现在你可以建立一个Language值写作:

let italian = Language.build(rawValue: "Italian") // Italian
let defaultValue = Language.build(rawValue: "Wrong input") // English
Run Code Online (Sandbox Code Playgroud)

  • 很棒的答案."自我= ......"非常宝贵.各种隐藏的Swift金块在这个郎:) (4认同)

Nat*_*ton 5

添加到Luca的解决方案以重新定义默认初始化,可以另外使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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

当我最初尝试这个时,它会产生多个错误.关键是要重新定义RawValue类型以保持一致性RawRepresentable.