Setelah membaca Cara menguji kesetaraan enum Swift dengan nilai terkait , saya menerapkan enum berikut:
enum CardRank {
case Number(Int)
case Jack
case Queen
case King
case Ace
}
func ==(a: CardRank, b: CardRank) -> Bool {
switch (a, b) {
case (.Number(let a), .Number(let b)) where a == b: return true
case (.Jack, .Jack): return true
case (.Queen, .Queen): return true
case (.King, .King): return true
case (.Ace, .Ace): return true
default: return false
}
}
Kode berikut berfungsi:
let card: CardRank = CardRank.Jack
if card == CardRank.Jack {
print("You played a jack!")
} else if card == CardRank.Number(2) {
print("A two cannot be played at this time.")
}
Namun, ini tidak dapat dikompilasi:
let number = CardRank.Number(5)
if number == CardRank.Number {
print("You must play a face card!")
}
... dan itu memberikan pesan kesalahan berikut:
Operator biner '==' tidak dapat diterapkan ke operan jenis 'CardRank' dan '(Int) -> CardRank'
Saya berasumsi ini karena mengharapkan tipe penuh dan CardRank.Number
tidak menentukan tipe keseluruhan, padahal CardRank.Number(2)
itu. Namun, dalam kasus ini, saya ingin mencocokkan nomor apa pun ; bukan hanya yang spesifik.
Jelas saya dapat menggunakan pernyataan sakelar, tetapi inti penerapan ==
operator adalah untuk menghindari solusi verbose ini:
switch number {
case .Number:
print("You must play a face card!")
default:
break
}
Apakah ada cara untuk membandingkan enum dengan nilai terkait sambil mengabaikan nilai yang terkait?
Catatan: Saya menyadari bahwa saya dapat mengubah kasus dalam ==
metode menjadi case (.Number, .Number): return true
, tetapi, meskipun itu akan mengembalikan true dengan benar, perbandingan saya masih akan terlihat seperti dibandingkan dengan nomor tertentu ( number == CardRank.Number(2)
; di mana 2 adalah nilai dummy) daripada angka apa pun ( number == CardRank.Number
).
sumber
Jack
,Queen
,King
,Ace
kasus di==
pelaksanaan operator untuk hanya:case (let x, let y) where x == y: return true
Jawaban:
Sunting: Seperti yang Etan tunjukkan, Anda dapat menghilangkan
(_)
kecocokan wildcard untuk menggunakan ini lebih bersih.Sayangnya, saya tidak percaya bahwa ada cara yang lebih mudah daripada
switch
pendekatan Anda di Swift 1.2.Namun, di Swift 2, Anda dapat menggunakan
if-case
pencocokan pola baru :let number = CardRank.Number(5) if case .Number(_) = number { // Is a number } else { // Something else }
Jika Anda ingin menghindari verbositas, Anda dapat mempertimbangkan untuk menambahkan
isNumber
properti yang dihitung ke enum Anda yang mengimplementasikan pernyataan switch Anda.sumber
assert(number == .Number)
. Saya hanya bisa berharap ini ditingkatkan di versi Swift yang lebih baru. = /default
kasus di satuswitch
blok untuk saat ini.Sayangnya di Swift 1.x tidak ada cara lain sehingga Anda harus menggunakan
switch
yang tidak seanggun versi Swift 2 di mana Anda dapat menggunakanif case
:if case .Number = number { //ignore the value } if case .Number(let x) = number { //without ignoring }
sumber
if
pernyataan, bukan sebagai ekspresi.Di Swift 4.2
Equatable
akan disintesis jika semua nilai terkait Anda sesuaiEquatable
. Yang perlu Anda lakukan hanyalah menambahkanEquatable
.enum CardRank: Equatable { case Number(Int) case Jack case Queen case King case Ace }
https://developer.apple.com/documentation/swift/equatable?changes=_3
sumber
Berikut pendekatan yang lebih sederhana:
enum CardRank { case Two case Three case Four case Five case Six case Seven case Eight case Nine case Ten case Jack case Queen case King case Ace var isFaceCard: Bool { return (self == Jack) || (self == Queen) || (self == King) } }
Tidak perlu membebani operator ==, dan memeriksa jenis kartu tidak memerlukan sintaks yang membingungkan:
let card = CardRank.Jack if card == CardRank.Jack { print("You played a jack") } else if !card.isFaceCard { print("You must play a face card!") }
sumber
Anda tidak membutuhkan
func ==
atauEquatable
. Cukup gunakan pola kasus pencacahan .let rank = CardRank.Ace if case .Ace = rank { print("Snoopy") }
sumber