본문 바로가기

프로그래밍/Swift

[Swift] @frozen은 무슨 의미일까?

반응형

@를 붙이면 자바에서는 Annotation이라고 부르던데, Swift에서는 Attributes라고 한다. 완전히 같은것인지는.. 잘 모르겠지만 비슷한것 같다.

 

네트워크 서비스를 구현하다가 Result라는 enum의 선언을 봤는데 @frozen이 붙어있었다. 잉 근데 도대체 이게 뭐지? 일단 얼었다는 뜻이니까.. 고정되어 있다는 것을 의미한다고 유추할 순 있었다. 그래서 찾아보니...

 

@frozen을 붙여주면 나중에 새로운 case가 추가되지 않는걸 약속한다는 의미란다. 근데 그걸 왜 약속해야 하지?

 

@frozen이 붙은것과 안붙은 것의 차이

@frozen이 없는 enum의 예시부터 확인해 보자.

func example1(_ sizeClass: UIUserInterfaceSizeClass) {
    switch sizeClass {
    case .regular:
        break
    case .unspecified:
        break
    case .compact:
        break
    }
}

 

UIUserInterfaceSizeClass는 3개의 case를 가지고 있다. 그래서 전부 다 switch에 구현해 줬는데도 아래와 같은 warning이 발생한다.

Switch covers known cases, but 'UIUserInterfaceSizeClass' may have additional unknown values, possibly added in future versions

 

대충 해석해보면 UIUserInterfaceSizeClass는 추가적인 case가 나중에 생길지도 모른다는 뜻이다. 그래서 fix를 해보면 @unknown default를 추가해준다.

func example1(_ sizeClass: UIUserInterfaceSizeClass) {
    switch sizeClass {
    		...
    @unknown default:
        fatalError()
    }
}

 

왜 @unknown을 붙여줘야 할까?

@unknown을 안붙여주고 그냥 default만 써주면 나중에 UIUserInterfaceSizeClass에 새로운 case가 추가된다고 해도 쥐도새도 모르게 새로운 case는 default로 빠져버린다. 즉, 추가된 case를 처리하지 못하게 된다는 뜻이다.

 

@unknown을 붙여주면 나중에 case가 추가 되었을 때  Switch must be exhaustive 라는 warning을 준다. 그래서 이것으로 새로운 case가 생겼다고 판단하여 처리할 수 있는것이다.

 

자 그럼 @frozen이 붙은 예시를 확인해보자. ComparisonResult이라는 enum에는 @frozen이 붙어있다.

func test2(n: ComparisonResult) {
    switch n {
    case .orderedAscending:
        break
    case .orderedDescending:
        break
    case .orderedSame:
        break
    }
}

 

@frozen이 붙은 enum을 switch 구문에 넣었을 때 warning이 발생하지 않는다. @frozen을 붙여 추가적인 case가 생기지 않는다는 것을 약속했기 때문이다.

 

따라서 @frozen을 붙여줌으로써 default 과정을 없애 불필요한 부분을 없애주고 컴파일 시간을 줄여준다고 한다. @frozen은 라이브러리에서만 적용되는 것으로 보인다.

 

 

 

 

참고: https://docs.swift.org/swift-book/ReferenceManual/Attributes.html

반응형