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"
}
}
}
私がすべての人型キーを知らないという問題は、人型のデフォルトのケースを処理する必要があり、それを説明するためには「とても怠lazな」キーとデフォルトの画像のキーになります。
webサービスからこの結果を取得するとしましょう。
[
{
name: "john",
key: "cool"
},
{
name: "paul",
key: "funny"
}
]
キー「面白い」を処理するためにデフォルトのケースが必要です
personオブジェクトの解析および作成中に列挙型を初期化する方法は次のとおりです。
if let personType = PersonType(rawValue:personTypeKey ?? "") {
self.personType = personType
}
else
またはより良いアプローチで、enum内の不明なキーのケースを処理し、それらのキーを説明およびデフォルトの画像として指定します。
Swift 3(おそらく2、わからない)で動作する別のアプローチ:
enum PersonType: String {
case cool = "cool"
case Nice = "Nice"
case soLazy = "so-lazy"
case other
}
let person = PersonType(rawValue: "funny") ?? .other
この場合、person変数はPersonType.other型です。
これの欠点は、.otherケースの生の文字列値がわからないことです。
生の型を削除し、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)
}
}
}
生の型を削除することの欠点は、既知のenum
値を解析するためのロジックを提供する必要があることです。ただし、利点は、実際の「不明な」値を後で使用できるように保ちながら、他のすべてを単一のUnknown
ケースに収めることができることです。
これはかなり近いですが、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
カスタム初期化子を作成する必要がありました。それ以外の場合は再帰的です。また、誤って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
これにより、「その他」のエラーの実際の値を取得でき、rawValueを使用して、Intベースの列挙型によく似た動作をすることができます。名前をマップする単一のcaseステートメントがありますが、それ以降は名前を使用でき、番号を参照する必要はありません。
そのようです:
init() {
self = .Cool
}
Swift 5.1では、デフォルト値を設定できるようになりました。コードは次のようになります。
enum PersonType {
case cool(String = "cool")
case Nice(String = "rude")
case soLazy(String = "so-lazy")
}
あなたの場合:
Enumのデフォルト値:default
計算プロパティを追加するか、またはinitをカスタマイズします。
public enum PersonType:String {
case Cool = "cool"
case Nice = "rude"
case SoLazy = "so-lazy"
/// add a `default` computer property
public static var `default`: PersonType {
return .SoLazy
}
/// add an customize init function
public init(person: String? = nil) {
if let person = person {
switch person {
case "cool": self = .Cool
case "rude": self = .Nice
case "so-lazy": self = .SoLazy
default: self = .SoLazy
}
} else {
self = .SoLazy
}
}
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"
}
}
}
使用するには:
if let personType = PersonType(rawValue:personTypeKey ?? "") {
self.personType = personType
} else {
self.personType = PersonType.default
}
または
if let personType = PersonType(rawValue:personTypeKey ?? "") {
self.personType = personType
} else {
self.personType = PersonType()
}
関連付けられた値を持つ列挙のデフォルト値:
public enum Gender {
case man
case woman
}
public enum PersonType {
case cool(Gender)
case Nice(Gender)
case soLazy(Gender)
public static var `default`: PersonType {
return PersonType.make.soLazy()
}
public enum Builder {
public static func cool() -> PersonType {
return PersonType.cool(.woman)
}
public static func Nice() -> PersonType {
return PersonType.Nice(.woman)
}
public static func soLazy() -> PersonType {
return PersonType.soLazy(.woman)
}
}
public static var make: PersonType.Builder.Type {
return PersonType.Builder.self
}
public var description: String {
switch self {
case .cool(let gender):
switch gender {
case .man: return "Cool boy"
case .woman: return "Cool girl"
}
case .Nice(let gender):
switch gender {
case .man: return "Nice boy"
case .woman: return "Nice girl"
}
case .soLazy(let gender):
switch gender {
case .man: return "its so lazy boy"
case .woman: return "its so lazy girl"
}
}
}
public var typeImage: String {
switch self {
case .cool(_):
return "cool.png"
case .Nice(_):
return "img_Nice.png"
case .soLazy(_):
return "lazy.png"
}
}
}
使用するには:
let onePersonType = PersonType.default
let anotherPersonType = PersonType.make.soLazy()
Ilya Puchka 'blog で見つかった2番目のケースソリューション。また、それは Swiftの提案 で言及されています。
このアプローチを試してください。
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"
}
}
}
質問に答えるには:
public enum PersonType:String {
case Cool = "cool"
case Nice = "rude"
case SoLazy = "so-lazy"
static var `default`: PersonType { return .SoLazy }
public init(rawValue: RawValue) {
switch rawValue {
case PersonType.Cool.rawValue: self = .Cool
case PersonType.Nice.rawValue: self = .Nice
case PersonType.SoLazy.rawValue: self = .SoLazy
default: self = .default
}
}
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"
}
}
}
これで、デフォルト値のフェイル可能なイニシャライザがないため、次のコードを置き換えます。
if let personType = PersonType(rawValue:personTypeKey ?? "") {
self.personType = personType
}
と:
personType = PersonType(rawValue: personTypeKey)
辞書はここの列挙型よりも適しているのではないかと思います:
let dict = [
"Cool": "cool",
"Nice": "rude",
"SoLazy": "so-lazy"
]
let personType = "unknown"
let personDescription = dict[personType] ?? "Unknown"
タイピングの削減、処理の高速化、デフォルトのケースのより自然な処理、拡張の容易化。