Notice
Recent Posts
Recent Comments
Link
관리 메뉴

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

[iOS - swift] enum의 RawPresentable과 associated type 개념 (Enum with raw type cannot have cases with arguments) 본문

iOS 응용 (swift)

[iOS - swift] enum의 RawPresentable과 associated type 개념 (Enum with raw type cannot have cases with arguments)

jake-kim 2023. 5. 2. 01:19

enum의 RawRresentable 개념

  • enum에서 각 case들은 rawValue(원시값)을 가질 수 있음
    • enum이 Rawpresentable을 따르게 되면 아래처럼 rawValue로도 초기화할 수 있고 rawValue 프로퍼티로 값을 가져올수도 있음
    • 즉 RawPresentable은 case문에 관해 값을 초기화하고 해당 값을 또 리턴할 있는 것
public protocol RawRepresentable<RawValue> {
    associatedtype RawValue

    init?(rawValue: Self.RawValue)

    var rawValue: Self.RawValue { get }
}

암묵적인 RawPresentable

  • enum을 만들 때 옆에 Int와 같은 타입을 따르게 되면 암묵적으로 RawValue가 Int타입인 값으로 설정됨
  • enum을 정의할때 아래처럼 Int 타입을 사용하면 상속도 아닌, 프로토콜 준수도 아닌 암묵적인 RawPresentable로 된다는 것이 핵심
enum Number: Int {
    case one
    case two
    case three
}

let number = Number(rawValue: 0) // RawPresentable을 따르므로 특정 값으로 초기화도 가능
print(number) // one

RawPresentable의 특성

  • case문에 각 case들은 associated type을 가질 수 있는데, RawPresentable이 있으면 associated type을 가질 수 없음
    • associated type은 case옆에 소괄호를 넣고 값을 넣을 수 있는 타입
enum SomeEnum {
    case a(Int) // a의 associated type은 Int 형태
}
  • SomeEnum이 Int형을 따르는 순간 암묵적으로 RawPresentable을 따르게 되므로 Enum with raw type cannot have cases with arguments 에러가 발생
    • RawPresentable이 있으면 associated type을 가질 수 없음
enum SomeEnum: Int {
    case a(Int) // Error: Enum with raw type cannot have cases with arguments
}
  • 단, associated type이 있지만 extension으로 RawPresentable 준수하면 사용이 가능
enum Fruit {
    case apple(SomeStruct)
    case banana
    case etc
}

extension Fruit: RawRepresentable {
    typealias RawValue = String
    
    var rawValue: String {
        switch self {
        case .apple:
            return "apple"
        case .banana:
            return "banana"
        case .etc:
            return "etc"
        }
    }
    
    init(rawValue: String) {
        switch rawValue {
        case "apple": self = .apple(SomeStruct())
        case "banan": self = .banana
        default: self = .etc
        }
    }
}

* 전체 코드: https://github.com/JK0369/ExRawPresentable.git

* 참고 

https://developer.apple.com/documentation/swift/rawrepresentable

Comments