Swift에서 관련 값을 무시하고 열거와 관련 값을 비교하는 방법은 무엇입니까?
Swift 열거형과 관련 값의 동일성을 테스트하는 방법을 읽은 후 다음 열거형을 구현했습니다.
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
}
}
다음 코드가 작동합니다.
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.")
}
그러나 다음은 컴파일되지 않습니다.
let number = CardRank.Number(5)
if number == CardRank.Number {
print("You must play a face card!")
}
다음과 같은 오류 메시지가 표시됩니다.
'==' 이진 연산자를 'CardRank' 및 '(Int) -> CardRank' 유형의 피연산자에 적용할 수 없습니다.
제 생각에 이것은 완전한 유형과CardRank.Number
전체 유형을 지정하지 않는 반면CardRank.Number(2)
네. 하지만, 이 경우 특정 숫자가 아닌 임의의 숫자와 일치하기를 원합니다.
분명히 나는 스위치 문을 사용할 수 있지만, 구현의 전체 요점은==
연산자는 이 장황한 솔루션을 피하는 것이었습니다.
switch number {
case .Number:
print("You must play a face card!")
default:
break
}
관련 값을 무시한 채 열거형을 관련 값과 비교할 수 있는 방법이 있습니까?
참고: 앞으로 사례를 변경할 수 있다는 것을 알고 있습니다.==
하는 방법.case (.Number, .Number): return true
하지만 정확하게 반환되지만, 제 비교는 여전히 특정 숫자와 비교되는 것처럼 보일 것입니다.number == CardRank.Number(2)
여기서 2는 임의의 숫자()보다 더미 값입니다.number == CardRank.Number
).
편집: Ethan이 지적했듯이, 당신은 생략할 수 있습니다.(_)
와일드카드 일치:
let number = CardRank.Number(5)
if case .Number = number {
// Is a number
} else {
// Something else
}
불행하게도, 당신의 것보다 더 쉬운 방법은 없다고 생각합니다.switch
Swift 1.2에서 접근합니다.
그러나 Swift 2에서는 새로운 기능을 사용할 수 있습니다.if-case
패턴 일치:
let number = CardRank.Number(5)
if case .Number(_) = number {
// Is a number
} else {
// Something else
}
장황한 내용을 피하고자 하는 경우 다음을 추가하는 것이 좋습니다.isNumber
스위치 문을 구현하는 열거형의 계산된 속성입니다.
안타깝게도 Swift 1.x에서는 다른 방법이 없으므로 사용해야 합니다.switch
당신이 사용할 수 있는 스위프트 2 버전만큼 우아하지 않습니다.if case
:
if case .Number = number {
//ignore the value
}
if case .Number(let x) = number {
//without ignoring
}
Swift 4.2에서Equatable
모든 관련 값이 다음과 일치하면 합성됩니다.Equatable
추가하기만 하면 됩니다.Equatable
.
enum CardRank: Equatable {
case Number(Int)
case Jack
case Queen
case King
case Ace
}
https://developer.apple.com/documentation/swift/equatable?changes=_3
연관된 값과 상관없이 두 열거형 사례가 "일치"할 경우 비교하기 위해 주로 수행하는 작업은 다음과 같습니다.
나는 의전이 있습니다.Matchable
:
protocol Matchable {
static func ~= (lhs: Self, rhs: Self) -> Bool
}
그런 다음 열거형을 따르도록 하겠습니다.
extension CardRank: Matchable {
static func ~= (lhs: Self, rhs: Self) -> Bool {
switch (lhs, rhs) {
case
(.number, .number),
(.jack, .jack),
(.queen, .queen),
(.king, .king),
(.ace, .ace):
return true
default:
return false
}
}
}
let card1: CardRank = .number(1)
let card2: CardRank = .number(2)
let card3: CardRank = .jack
print(card1 ~= card2) // true
print(card1 ~= card3) // false
다음은 더 간단한 접근 방식입니다.
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)
}
}
== 연산자를 오버로드할 필요가 없으며, 카드 유형을 확인할 때 다음과 같은 혼란스러운 구문이 필요하지 않습니다.
let card = CardRank.Jack
if card == CardRank.Jack {
print("You played a jack")
} else if !card.isFaceCard {
print("You must play a face card!")
}
나는 그것에 순응하고 싶지 않았습니다.Equatable
(그것도 나에게 도움이 되지 않았다) 그리고 나는 특정 사례가 아닌 다른 사례를 필터링하고 싶었다, 그래서 단순히 쓰는 대신.card != .Number
저는 다음과 같이 써야 했습니다.(이 질문에 대한 코드를 조정했습니다.)
enum CardRank {
...
var isNumber: Bool {
if case .Number = self { return true }
return false
}
}
그래서 나는 복잡한 조건에서 숫자가 아닌 것을 쓸 수 있습니다.
if something && !card.isNumber { ... }
그냥 쓸 수 있으면 좋겠어요.card != .Number
그러나 컴파일러는 항상 표현의 유형이 더 많은 맥락 없이 모호하다고 불평했습니다.아마도 다가오는 빠른 버전에서!
필없습다가 필요 없습니다.func ==
또는Equatable
열거형 대소문자 패턴을 사용하면 됩니다.
let rank = CardRank.Ace
if case .Ace = rank { print("Snoopy") }
extension CardRank {
func isSameCaseAs(_ other: CardRank) -> Bool {
switch (self, other) {
case (.Number, .Number),
(.Jack, .Jack),
(.Queen, .Queen),
(.King, .King),
(.Ace, .Ace):
return true
default:
return false
}
}
}
let number = CardRank.Number(1)
let otherNumber = CardRank.Number(2)
number.isSameCaseAs(otherNumber) // true
확장을 만들고 관련 유형을 무시하기만 하면 됩니다.
Swift 5.3에서는 비교 가능한 열거형 기능을 사용할 수 있습니다.
enum CardRank: Comparable {
case Number(Int)
case Jack
case Queen
case King
case Ace
}
let cards: [CardRank] = [
.Queen, .Number(8), .Ace, .Number(3), .King
]
print(cards.sorted())
// [.Number(3), .Number(8), .Queen, .King, .Ace]
언급URL : https://stackoverflow.com/questions/31548855/how-to-compare-enum-with-associated-values-by-ignoring-its-associated-value-in-s
'programing' 카테고리의 다른 글
도커가 사용 중이지만 도커 컨테이너가 없습니다. (0) | 2023.08.14 |
---|---|
PDO 사용법에 대한 좋은 튜토리얼이 있습니까? (0) | 2023.08.14 |
메소드를 사용하여 jQuery 플러그인을 만드는 방법은 무엇입니까? (0) | 2023.08.14 |
sockJS+Spring 웹소켓에서 "user"가 convertAndSendToUser에서 작동하는 곳은 어디입니까? (0) | 2023.08.14 |
여러 인덱스가 함께 작동할 수 있습니까? (0) | 2023.08.14 |