iOS 기본 (swift)
[iOS - swift] Comparable (+ Clamped 기능 구현)
jake-kim
2022. 6. 10. 22:54
Comparable
- 해당 프로토콜을 준수하면 등호, 부등호 연산자 기능을 사용할 수 있도록 하는 것
- Comparable은 내부적으로 Equtable을 준수
- Equtable 프로토콜은 == 연산자를 위한 프로토콜이며 개념은 이전 포스팅 글 참고
// Swift.Misk
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
}
- Comparable 사용 예
- 내부적으로 Date가 Comprable을 준수하고 있지만 아래처럼 재정의를 사용이 가능
extension Date: Comparable {
// Comprable 준수
static func < (lhs: Date, rhs: Date) -> Bool {
if lhs.year != rhs.year {
return lhs.year < rhs.year
} else if lhs.month != rhs.month {
return lhs.month < rhs.month
} else {
return lhs.day < rhs.day
}
}
// Equtable 준수
static func == (lhs: Date, rhs: Date) -> Bool {
return lhs.year == rhs.year && lhs.month == rhs.month
&& lhs.day == rhs.day
}
}
Clamped 구현
* clamped: to fasten two things together
- Clapmed는 특정 값이 있을때 특정 값을 범위내의 값만 나오도록 하는 연산자를 의미 (범위 밖의 값일땐 범위의 하한 or 상한에 가까운 값을 반환)
let n1 = 123
let n2 = n1.clamped(0...100) // 100
let n3 = -50
let n4 = n3.clamped(0...100) // 0
let n5 = 30
let n6 = n5.clamped(0...100) // 30
- Comparable을 따르면 비교연산을 사용할 수 있으므로, Comparable을 extension하여 구현
- 인수는 ClosedRange 값 (닫힌 구간 = 양 끝을 포함하는 범위)을 받도록 정의
extension Comparable {
func clamped(_ range: ClosedRange<Self>) -> Self {
}
}
- max, min 함수를 한번씩 사용하여 알맞은 값 획득
extension Comparable {
func clamped(_ range: ClosedRange<Self>) -> Self {
min(max(self, range.lowerBound), range.upperBound)
}
}
propertyWrapper에 clamped 사용 방법
- propertyWrapper로 Clamped를 정의하여 사용 방법
@Clamped(value: 5, range: (0...100))
var myValue
myValue = 123 // 100
myValue = -5 // 0
- @propertyWrapper 선언
- 제네릭 타입은 Comparable을 따르게하여 clamped를 사용할 수 있는 대상으로 한정
@propertyWrapper
struct Clamped<T: Comparable> {
}
- value와 range 타입 정의
@propertyWrapper
struct Clamped<T: Comparable> {
var value: T
var range: ClosedRange<T>
var wrappedValue: T {
}
}
- wrappedValue의 get, set 정의
var wrappedValue: T {
get { self.value }
set { self.value = newValue.clamped(self.range) }
}
* 참고
https://stackoverflow.com/a/40868784
https://developer.apple.com/documentation/swift/comparable