Swift中Enum的默认值

iOS*_*eek 11 enums ios data-structures swift swift2

我有一个enum:

public enum PersonType:String {

 case Cool                       = "cool"
 case Nice                       = "rude"
 case SoLazy                     = "so-lazy"

 public var description: String {
    switch self {
    case .Cool:
        return "Cool person"
    case .Nice:
        return "Nice person"
    case .SoLazy:
        return "its so lazy person"
    }
}


 public var typeImage: String {
    switch self {
    case .Cool:
        return "cool.png"
    case .Nice:
        return "img_nice.png"
    case .Solazy:
        return "lazy.png"
    }
   }  

}
Run Code Online (Sandbox Code Playgroud)

问题我不知道所有的人类型键,所以我需要处理类型为人的默认情况,并给它描述将是它的关键像"so-lazy"和默认图像.

假设我从Web服务获得此结果:

[
    {
        name: "john",
        key: "cool"
    },
    {
        name: "paul",
        key: "funny"
    }
]
Run Code Online (Sandbox Code Playgroud)

我需要一个默认的案例来处理关键的"搞笑"

这是我在解析和创建person对象时如何初始化我的枚举:

if let personType = PersonType(rawValue:personTypeKey ?? "") {
   self.personType = personType
}
Run Code Online (Sandbox Code Playgroud)

我想要一个else或更好的方法来处理枚举中未知键的情况,并给它们作为描述和默认图像的键.

Bud*_*ddy 16

另一种在Swift 3中工作的方法(可能是2,不知道):

enum PersonType: String {
    case cool = "cool"
    case nice = "nice"
    case soLazy = "so-lazy"
    case other
}

let person = PersonType(rawValue: "funny") ?? .other
Run Code Online (Sandbox Code Playgroud)

在这种情况下,person变量的类型为PersonType.other.

这样做的缺点是你不知道.other案例的原始字符串值.


das*_*ght 14

删除原始类型,并使用enum相关值:

public enum PersonType {
    case Cool
    case Nice
    case SoLazy
    case Unknown(String)
    static func parse(s:String) -> PersonType {
        switch s {
            case "Cool" : return .Cool
            case "Nice" : return .Nice
            case "SoLazy" : return .SoLazy
            default: return Unknown(s)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

删除原始类型的缺点是必须提供一些逻辑来解析已知enum值.然而,好处是你可以将任何其他东西放入一个Unknown案例中,同时保持实际的"未知"值可供以后使用.


Rui*_*res 9

在 Swift 5.1 中,现在可以设置默认值。你的代码看起来像这样:

enum PersonType {
  case cool(String = "cool")
  case nice(String = "rude")
  case soLazy(String = "so-lazy")
}
Run Code Online (Sandbox Code Playgroud)


Wil*_* Hu 7

像这样:

init() {
    self = .Cool
}
Run Code Online (Sandbox Code Playgroud)


pos*_*sen 7

这非常接近,但是我希望能够存储可以与之关联的值,就像使用C一样。

enum Errors: Int {
    case transactionNotFound = 500
    case timeout = -1001
    case invalidState = 409
    case notFound = 404
    case unknown

    init(value: Int) {
        if let error = Errors(rawValue: value) {
            self = error
        } else {
            self = .unknown
        }
    }
}

Errors(value: 40) // .unknown
Errors(value: 409) // .invalidState
Errors(value: 500) // .transactionNotFound
Run Code Online (Sandbox Code Playgroud)

必须创建一个自定义初始化程序,否则它是递归的。并且仍然有可能偶然使用rawValue初始化程序进行创建。

但是,这感觉更加快速,我删除了: Int允许使用关联值的类型说明符,现在在以下特殊情况下,我们不做任何特殊处理other

enum Errors2 {
    case transactionNotFound
    case timeout
    case invalidState
    case notFound
    case other(Int)

    init(rawValue: Int) {
        switch rawValue {
        case 500:
            self = .transactionNotFound
        case -1001:
            self = .timeout
        case 409:
            self = .invalidState
        case 404:
            self = .notFound
        default:
            self = .other(rawValue)
        }
    }
}

Errors2(rawValue: 40) // .other(40)
Errors2(rawValue: 409) // .invalidState
Errors2(rawValue: 500) // .transactionNotFound
Errors2(rawValue: -1001) // .timeout
Run Code Online (Sandbox Code Playgroud)

这样,我可以获取“其他”错误的实际值,并且可以使用rawValue,因此它的行为很像基于Int的枚举。仅存在一个case语句来映射名称,但是从那时起,您可以使用名称,而无需引用数字。


小智 2

尝试这种方法。

public enum PersonType:String {

    case Cool                       = "cool"
    case Nice                       = "rude"
    case SoLazy                     = "so-lazy"

    static let allKeys = [Cool.rawValue, Nice.rawValue, SoLazy.rawValue]
}

extension PersonType
{
    func description(personTypeKey : String) -> String {

        if PersonType.allKeys.contains(personTypeKey)
        {
            switch self {
            case .Cool:
                return "Cool person"
            case .Nice:
                return "Nice person"
            case .SoLazy:
                return "its so lazy person"
            }
        }
        else
        {
            return "YourTextHere"
        }
    }

    func typeImage(personTypeKey : String) -> String {

        if PersonType.allKeys.contains(personTypeKey)
        {
            switch self {
            case .Cool:
                return "cool.png"
            case .Nice:
                return "img_nice.png"
            case .SoLazy:
                return "lazy.png"
            }
        }
        else
        {
            return "YourImageHere"
        }
    }
}
Run Code Online (Sandbox Code Playgroud)