관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] Comparable (+ Clamped 기능 구현) 본문

iOS 기본 (swift)

[iOS - swift] Comparable (+ Clamped 기능 구현)

jake-kim 2022. 6. 10. 22:54

Comparable

  • 해당 프로토콜을 준수하면 등호, 부등호 연산자 기능을 사용할 수 있도록 하는 것

https://developer.apple.com/documentation/swift/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

 

 

 

Comments