우리는 코딩을 하면서 필요한 것들을 클래스, 구조체, 열거형, 함수를 통해 구현하곤 하죠..
그런데 그러한 객체들을 배열에 넣어 정렬하거나, 비교하거나 하는 일들이 종종! 일어납니다.
그래서 요번에는 위 내용들을 실현하기 위한 Comparable에 관련 된 글을 포스팅 하려합니다! 👏🏻👏🏻👏🏻
글 읽기 앞서 기본적인 프로토콜 관련 내용은 아셔야 합니다! 그럼 출발
git : 예제소스
Comparable
프로토콜에 익숙하시거나, 제 블로그 내 Protocol 관련 글을 읽으셨다면, Comparable 보시고 ?!?! 프로토콜인가 하고 추측하셨어야합니다!
맞습니다 Comparable 은 swift에서 기본적으로 제공하는 대소를 비교하기 위한 프로토콜입니다.
우리는 기본 자료형 Int, String, Double 에 대해 당연하게 > , < , >= , <= 비교연산자를 써왔지만, 기본 자료형도 마찬가지로 Comparable 프로토콜을 준수하고 있기 때문에 비교연산자를 사용 할 수 있었던 것입니다.
let tenInt: Int = 10
let fiveInt: Int = 5
print(fiveInt < tenInt) // true
Comparable이 어떻게 생겼는지 확인하면, 아래와 같습니다. Comparable 자체적으로 Equatable을 준수하고 있기 때문에, Comparable을 준수하기 위해서는 Equatable도 준수해줘야겠군요..
여담이지만, 구현부를 확인해보는 습관을 추천드립니다.. 저도 익숙하지 않고, 딱히 엄청 궁금하진 않지만?!? 공식문서라던지 cmd + control을 통해보곤 합니다! 개발하는데 있어 최고의 가이드라인이라고 생각합니다
public protocol Comparable : Equatable {
static func < (lhs: Self, rhs: Self) -> Bool
static func <= (lhs: Self, rhs: Self) -> Bool
static func >= (lhs: Self, rhs: Self) -> Bool
static func > (lhs: Self, rhs: Self) -> Bool
}
Class에서 준수
Person class 에서 나이를 기준으로 Person 대소 비교를 하기 위해 Comparalbe을 준수하였습니다.
class Person: Comparable {
var age: Int
var name: String
init(_ name: String, _ age: Int) {
self.name = name
self.age = age
}
static func < (lhs: Person, rhs: Person) -> Bool {
return lhs.age < rhs.age
}
static func == (lhs: Person, rhs: Person) -> Bool {
return lhs.age == rhs.age
}
}
var kimPerson = Person("Kim", 20)
var leePerson = Person("Lee", 15)
print(kimPerson < leePerson) // false
∙ Comparable을 채택만 하면, < , == 구현해주지 않았기 때문에 컴파일 오류가 발생합니다! 하긴 생각해보면 당연합니다. 대소 비교를 위해 Comparable을 채택하였는데, 어떤 기준으로 비교할 지 가르쳐주지 않았으니까요!
∙ == 의 경우 Equatable 준수를 위함입니다!
Struct에서 준수
Developer struct에서 이름을 기준으로 Developer 대소 비교를 하기 위해 Comparable을 준수
struct Developer: Comparable {
var name: String
var developLanguage: String
static func < (lhs: Developer, rhs: Developer) -> Bool {
lhs.name < rhs.name
}
}
var kimDeveloper = Developer(name: "Kim", developLanguage: "Python")
var leeDeveloper = Developer(name: "Lee", developLanguage: "Java")
print(kimDeveloper < leeDeveloper) // true
∙ Class와 마찬가지로 Comparable을 채택하면, < 구현해주지 않았기 때문에 오류가 발생합니다.
∙ Class와 차이는 Equatable의 == 을 구현해주지 않았음에도 오류가 발생하지 않는다는 것 입니다. struct는 default로 == 같은 경우 모든 저장프로퍼티 동일 한 경우로 셋 되어 있기 때문입니다. 만약 기준을 바꿔주고 싶다면, ==에 관해 구현해주면 됩니다!
Enum에서 준수
DeveloperLanguage Enum에서 DeveloperLanguage 대소 비교를 위해 Comparable 준수
enum DevelopLangaugae: Int, Comparable {
case swift = 1, java = 2, python = 3, cLaungage = 4
var classRoom: String {
switch self {
case .swift:
return "A"
case .java:
return "A"
case .python:
return "B"
case .cLaungage:
return "C"
}
}
static func < (lhs: DevelopLangaugae, rhs: DevelopLangaugae) -> Bool {
lhs.rawValue < rhs.rawValue
}
// static func == (lhs: DevelopLangaugae, rhs: DevelopLangaugae) -> Bool {
// return lhs.classRoom == rhs.classRoom
// }
}
print(DevelopLangaugae.swift == DevelopLangaugae.java) // false
∙ Enum 또한 < 구현이 필요합니다!
∙ == 같은 경우 기본적으로 정의 case 타입에 따라 비교가 됩니다… 혹시나 궁금해서 == 구현 할 경우 구현 기준을 따를까 했는데, 따릅니다!
정리
∙ > , < , >= , <= 사용을 위해선 Comparable을 준수해야한다. Comparable은 Equatable을 준수하기 때문에, Equatable도 준수해야한다.
∙ Struct 와 Enum 은 기본적인 Equatable 정의가 있으나, Class는 정의되어 있지 않기 때문에 반드시 정의해줘야한다.
https://babbab2.tistory.com/150
https://babbab2.tistory.com/148
'알고리즘 & 문제풀이' 카테고리의 다른 글
프로그래머스 - L1 크기가 작은 부분 문자열 (0) | 2023.02.04 |
---|---|
자료구조 (0) | 2023.02.03 |
프로그래머스 - L1 문자열 내 마음대로 정렬하기 (0) | 2023.02.03 |
프로그래머스 - L1 최대공약수와 최소공배수 (0) | 2023.01.31 |
프로그래머스 - L1 문자열 내 p와 y의 개수 (0) | 2023.01.30 |