인수가 있는 열거형에 대해 if-else 비교를 수행하는 방법
언어:스위프트 2.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
다음과 같이 세 개의 열거형에 모두 사용할 수 있습니다.
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 문에 있는 단일 =와 함께 사용합니다.이것은 처음에는 약간 반직관적이지만 꼭 같습니다.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에서 열거형이 원시 유형을 사용하거나 관련 값이 없는 경우에만 열거형 방정식을 무료로 얻을 수 있다는 것입니다(두 가지를 동시에 사용할 수 없음).하지만 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...?
따라서 관련 값을 가진 열거형을 사용하려면 사용자가 직접 열거형에 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 Barcode {
case upca(Int, Int)
case qrCode(String)
case none
}
만약 우리가 동등한 연산자를 확인한다면,==
그것은 실패할 것입니다.
// Error: binary operator '==' cannot be applied to two Barcode operands
Barcode.qrCode("code") == Barcode.qrCode("code")
Equatable Protocol을 사용하여 이 문제를 해결하는 방법은 무엇입니까?
extension Barcode: Equatable {
}
func ==(lhs: Barcode, rhs: Barcode) -> Bool {
switch (lhs, rhs) {
case (let .upca(codeA1, codeB1), let .upca(codeA2, codeB2)):
return codeA1 == codeA2 && codeB1 == codeB2
case (let .qrCode(code1), let .qrCode(code2)):
return code1 == code2
case (.None, .None):
return true
default:
return false
}
}
Barcode.qrCode("code") == Barcode.qrCode("code") // true
Barcode.upca(1234, 1234) == Barcode.upca(4567, 7890) // false
Barcode.none == Barcode.none // true
언급URL : https://stackoverflow.com/questions/44061147/how-to-do-an-if-else-comparison-on-enums-with-arguments
'programing' 카테고리의 다른 글
Powershell을 사용하여 로컬 보안 정책 수정 (0) | 2023.08.30 |
---|---|
jQuery: .attr(); 메서드를 통해 두 개의 속성 추가 (0) | 2023.08.30 |
Twitter 부트스트랩을 사용하여 알림을 자동으로 닫는 방법 (0) | 2023.08.30 |
재활용자 보기:불일치가 탐지되었습니다.잘못된 품목 위치 (0) | 2023.08.30 |
js를 통해 파일 선택 대화 상자를 여는 방법은 무엇입니까? (0) | 2023.08.30 |