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案例中,同时保持实际的"未知"值可供以后使用.
在 Swift 5.1 中,现在可以设置默认值。你的代码看起来像这样:
enum PersonType {
case cool(String = "cool")
case nice(String = "rude")
case soLazy(String = "so-lazy")
}
Run Code Online (Sandbox Code Playgroud)
这非常接近,但是我希望能够存储可以与之关联的值,就像使用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)