관리 메뉴

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

[iOS - swift] OptionSet 개념 (enum case + set) 본문

iOS 응용 (swift)

[iOS - swift] OptionSet 개념 (enum case + set)

jake-kim 2023. 8. 15. 00:11

OptionSet 개념

  • enum-case의 case와 같이 사용할 수 있고 동시에 set 연산자인 insert, remove 등도 사용할 수 있는 API

https://developer.apple.com/documentation/swift/optionset?changes=_5

  • OptionSet 프로토콜 형태
    • SetAlgebra는 set의 연산자를 정의해놓은 프로토콜
public protocol OptionSet : RawRepresentable, SetAlgebra {
    associatedtype Element = Self

    init(rawValue: Self.RawValue)
}
  • SetAlgebra 형태
/// - `S() == []`
/// - `x.intersection(x) == x`
/// - `x.intersection([]) == []`
/// - `x.union(x) == x`
/// - `x.union([]) == x`
/// - `x.contains(e)` implies `x.union(y).contains(e)`
/// - `x.union(y).contains(e)` implies `x.contains(e) || y.contains(e)`
/// - `x.contains(e) && y.contains(e)` if and only if
///   `x.intersection(y).contains(e)`
/// - `x.isSubset(of: y)` implies `x.union(y) == y`
/// - `x.isSuperset(of: y)` implies `x.union(y) == x`
/// - `x.isSubset(of: y)` if and only if `y.isSuperset(of: x)`
/// - `x.isStrictSuperset(of: y)` if and only if
///   `x.isSuperset(of: y) && x != y`
/// - `x.isStrictSubset(of: y)` if and only if `x.isSubset(of: y) && x != y`
public protocol SetAlgebra<Element> : Equatable, ExpressibleByArrayLiteral {
...
}

OptionSet 사용법

  • enum-case문과 같이 case를 여러개 정의
    • static let으로 선언하고, bitwise 연산을 통해 2의 제곱형태로 선언
    • 1 << 0는 십진수로 1
    • 1 << 1는 십진수로 2
    • ...
  • bitwise 형태로 선언하는 이유? bitwise 연산은 하드웨어 레벨에서 빠른 연산이므로 이를 사용하는데, 그 중 값을 구분할 수 있는 정수 값중 가장 작은 값인 2의 제곱형태를 채택
struct ShippingOptions: OptionSet {
    let rawValue: Int

    static let nextDay    = ShippingOptions(rawValue: 1 << 0)
    static let secondDay  = ShippingOptions(rawValue: 1 << 1)
    static let priority   = ShippingOptions(rawValue: 1 << 2)
    static let standard   = ShippingOptions(rawValue: 1 << 3)

    static let express: ShippingOptions = [.nextDay, .secondDay]
    static let all: ShippingOptions = [.express, .priority, .standard]
}
  • 사용하는 쪽에서는 위 선언된 변수들을 마치 enum-case와 같이 사용하고 Set 연산자도 사용할 수 있는 형태
    • enum-case 기능과 Set 기능 사용 가능
let singleOption: ShippingOptions = .priority
let multipleOptions: ShippingOptions = [.nextDay, .secondDay, .priority]
let noOptions: ShippingOptions = []

switch singleOption {
case .nextDay:
    print("nextDay")
case .all:
    print("all")
default:
    print("default")
}

* 참고

https://developer.apple.com/documentation/swift/optionset?changes=_5 

 

Comments