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

时间:2016-01-31 21:23:58

标签: ios swift enums initialization

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

public init(fromRawValue: String){
        self = Language(rawValue: fromRawValue) ?? .English
}

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

public init(rawValue: String){
        self = Language(rawValue: fromRawValue) ?? .English
}

但是我遇到了运行时异常且访问不正确。我可以以某种方式使它工作或我只是必须使用这个新的,我不能覆盖原来的不是可选的吗?

我想知道是否有可能从rawValue覆盖原始init而不是使用可用的全新的原始init。

2 个答案:

答案 0 :(得分:96)

默认初始值设定项为nil。这意味着如果收到的参数与有效的枚举情况不匹配,则返回enum Language: String { case english = "English", italian = "Italian", french = "French" init(fromRawValue: String){ self = Language(rawValue: fromRawValue) ?? .english } }

现在你要做两件不兼容的事情:

  1. 您希望重新定义默认的初始化程序,使其无法使用。实际上,您希望在收到的参数无效时创建默认枚举值。
  2. 在您重新定义的初始化程序中,您希望使用新名称的初始化程序调用可用的初始化程序(不再存在)。
  3. 这是不可能的,我可能的解决方案如下:

    1)创建不同的init

    使用默认值,不同的参数名称定义一个新的不可用的初始化程序,在其中调用默认的可用初始化程序。

    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
            }
        }
    }
    

    2)重新定义默认的init

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

    enum Language: String {
    
        case english = "English", italian = "Italian", french = "French"
    
        static func build(rawValue: String) -> Language {
            return Language(rawValue: rawValue) ?? .english
        }
    }
    

    3)创建静态函数

    Language

    现在您可以构建let italian = Language.build(rawValue: "Italian") // Italian let defaultValue = Language.build(rawValue: "Wrong input") // English 值写作:

    git log --pretty=oneline

答案 1 :(得分: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
        }
    }
}

当我最初尝试此操作时,它会产生多个错误。关键是重新定义RawValue typealias以保持与RawRepresentable的一致性。