引数を持つ列挙型のif-else比較の方法 [重複]について
2023-10-12 07:23:46
質問
言語 : Swift2.3
例えば......様々な種類の列挙型を紹介しましょう。
enum Normal {
case one
case two, three
}
enum NormalRaw: Int {
case one
case two, three
}
enum NormalArg {
case one(Int)
case two, three
}
Switch
はこのように3つの列挙型で使うことができます。
var normal: Normal = .one
var normalRaw: NormalRaw = .one
var normalArg: NormalArg = .one(1)
switch normal {
case .one: print("1")
default: break
}
switch normalRaw {
case .one: print(normalRaw.rawValue)
default: break
}
switch normalArg {
case .one(let value): print(value)
default: break
}
if-else文で比較できるのは
Normal
と
NormalRaw
については、エラーメッセージが表示されます。
NormalArg
というエラーメッセージが表示され、コードを実行することができません。
二項演算子 '==' は、以下の型のオペランドには適用できません。
NormalArg
と_
以下はコード例です。
if normal == .two { // no issue
.. do something
}
if normalRaw == .two { // no issue
.. do something
}
if normalArg == .two { // error here (the above message)
.. do something
}
if normalArg == .one(_) { // error here (the above message)
.. do something
}
if normalArg == .three { // error here (the above message)
.. do something
}
何かアイデアはありますか?私はこのコードで本当に何もしていないのですが、なぜ比較ができないのか不思議に思っています。
どのように解決するのですか?
コツは、実際に==でチェックするのではなく、その前に
case
キーワードを使用して、if 文の中で 1 つの = を併用することです。これは最初のうちは少し直感に反しますが、ちょうど
if let
と同じように、すぐに慣れることができます。
enum Normal {
case one
case two, three
}
enum NormalRaw: Int {
case one = 1
case two, three
}
enum NormalArg {
case one(Int)
case two, three
}
let normalOne = Normal.one
let normalRawOne = NormalRaw.one
let normalArgOne = NormalArg.one(1)
if case .one = normalOne {
print("A normal one") //prints "A normal one"
}
if case .one = normalRawOne {
print("A normal \(normalRawOne.rawValue)") //prints "A normal 1"
}
if case .one(let value) = normalArgOne {
print("A normal \(value)") //prints "A normal 1"
}
ポイントは、Swiftでは、enumが生の型を使用する場合、または関連する値がない場合、無料でenumの等式を得るだけです(試してみてください、同時に両方を持つことはできません)。しかし、Swift は関連する値を持つケースを比較する方法を知りません - 私はそれがどのようにできるかを意味します。この例を見てみましょう。
Normal.one == .one //true
Normal.one == .two //false
NormalRaw.one == .one //true
NormalRaw.one == .two //false
NormalArg.one(1) == .one(1) //Well...?
NormalArg.one(2) == .one(1) //Well...?
NormalArg.one(1) == .two //Well...?
これで、なぜこれが箱から出してもうまくいかないのかがはっきりしたのではないでしょうか。
class Special {
var name: String?
var special: Special?
}
enum SpecialEnum {
case one(Special)
case two
}
var special1 = Special()
special1.name = "Hello"
var special2 = Special()
special2.name = "World"
special2.special = special1
SpecialEnum.one(special1) == SpecialEnum.one(special2) //Well...?
そのため、値を関連付けたenumが必要な場合は、自分でenumにEquatableプロトコルを実装する必要があります。
enum NormalArg: Equatable {
case one(Int)
case two
static func ==(lhs: NormalArg, rhs: NormalArg) -> Bool {
switch (lhs, rhs) {
case (let .one(a1), let .one(a2)):
return a1 == a2
case (.two,.two):
return true
default:
return false
}
}
}
関連
-
[解決済み] enumを列挙するには
-
[解決済み] intをenumにキャストするにはどうすればよいですか?
-
[解決済み] Javaで文字列値からenum値を取得する方法
-
[解決済み] Pythonで'Enum'を表現するにはどうしたらいいですか?
-
[解決済み] Goでenumを表現する慣用的な方法は何ですか?
-
[解決済み] 列挙型をサブクラス化して、新しい要素を追加することはできますか?
-
[解決済み] enumとは何か、なぜ有用なのか?
-
[解決済み] Swift 3で現在の日付を取得する?[クローズド]
-
[解決済み] Swiftでenumの関連値を無視して比較する方法は?
-
[解決済み] SwiftUIでリストの左右のパディングを削除する方法は?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Swift 3でカスタム通知を作成するには?
-
[解決済み] SwiftUIのForEachでインデックスを取得する
-
[解決済み] Swiftでenumの関連値を無視して比較する方法は?
-
[解決済み] Swift で型に表示されるテキスト表現を変更するにはどうしたらいいですか?
-
[解決済み] Swiftで失敗しないイニシャライザーを実装するためのベストプラクティス
-
[解決済み] SwiftUIでビューを動的に隠す
-
[解決済み] SwiftUIでリストの背景色を変更するには?
-
[解決済み] Swiftの定数。構造体か列挙型か
-
[解決済み] NSUserdefaultsの配列の保存と読み込みはどのように行うのですか?
-
[解決済み] 弱い自分はどこへ行くのか?