default ? @unknown default ?

Zion·2022년 1월 19일
1

며칠 전에 Swift Docs에서 'Control Flow'를 읽어봤다.
음 고렇지 하면서 읽던 중
스터디원들과 질문 타임 시간에 Switch문에서 @unknown default에 대해 알게 됐다?!

드래그 한 곳을 보자.
(switch할) value에 대해 적절한 case가 제공되지 않는다면 default case를 사용해서 명시적으로 선언된 case를 카바 칠 수 있다고 한다.

혼자 읽을 때 끄덕끄덕 하고 넘어갔는데
스터디원분이 @unknown default의 존재를 알려 주셨다.

그게 뭔데.

@unknown default

https://useyourloaf.com/blog/swift-5-frozen-enums/
https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md

직관적으로 해석했을 때는 '알지 못하는 default' 이다.
위에 링크에 있는 내용을 해석해 봤다.

그 전에, 배경지식 +

frozen ? nonfrozen ?


미래에 새로운 enum case 가 추가 될 enum이라면 nonfrozen

@unknown

In Swift 4.2, enums imported from C and enums defined in the standard library and overlays are either frozen or non-frozen( Grammatical note: They are not "unfrozen" because that implies that they were frozen at one point.
-> Swift 4.2 에서 C로부터 import되거나 standard library에서 정의된 그리고 overlays된 enum들은 frozen이거나 nonfrozen이다.

When a client tries to switch over a non-frozen enum, they should include a "catch-all" case of some kind (default, case , etc). In Swift 5 mode, omitting this case will result in a warning.
-> 클라이언트가 non-frozen enum을 넘어서 바꾸려 한다면, default나 case
등등과 같은 "catch-all" case 들을 포함해야한다. Swift5에선, 이런 케이스들을 제거하면서 warning으로 야기시킨다.

switch excuse {
case .eatenByPet:
  // …
case .thoughtItWasDueNextWeek:
  // …
}

다음과 같이 excuse를 case 별로 분기할 수 있게 만들어 놨다고 하자.

The downside of using a default case is that the compiler can no longer alert a developer that a particular enum has elements that aren't explicitly handled in the switch. To remedy this, switch cases will gain a new attribute, @unknown.

switch excuse {
case .eatenByPet:
  // …
case .thoughtItWasDueNextWeek:
  // …
@unknown default:
  // …
}

Like the regular default, @unknown default matches any value; it is a "catch-all" case. However, the compiler will produce a warning if all known elements of the enum have not already been matched. This is a warning rather than an error so that adding new elements to the enum remains a source-compatible change. (This is also why @unknown default matches any value rather than just those not seen at compile-time.)
-> 보통 default와 마찬가지로, @unknown default는 모든 value와 match한다.
이건 "catch-all" case다. 그러나 만약 모든 아는 enum의 원소들이 아직 match되지 않았다면 컴파일러는 warning을 띄운다.

@unknown may only be applied to default or a case consisting of the single pattern _. Even in the latter case, @unknown must be used with the last case in a switch. This restriction is discussed further in the "unknown patterns" section under "Future directions".

if all enums in the pattern being matched by @unknown are explicitly annotated as frozen, or if there are no enums in the pattern at all. This is a warning rather than an error so that annotating an enum as frozen remains a source-compatible change. If the pattern contains any enums that are implicitly frozen (i.e. because it is a user-defined Swift enum), @unknown is permitted, in order to make it easier to adapt to newly-added cases.
-> @unknown과 일치하는 패턴의 모든 열거형이 명시적으로 고정된 것으로 주석이 지정되거나 패턴에 열거형이 전혀 없는 경우. 이는 enum에 고정된 주석을 추가하는 것이 소스 호환 변경으로 유지되도록 하는 오류라기 보다는 경고입니다. 패턴이 암시적으로 고정된 열거형을 포함하는 경우(즉, 사용자 정의 Swift 열거형이기 때문에) 새로 추가된 사례에 더 쉽게 적응할 수 있도록 @unknown이 허용됩니다.

@unknown has a downside that it is not testable, since there is no way to create an enum value that does not match any known cases, and there wouldn't be a safe way to use it if there was one. However, combining @unknown with other cases using fallthrough can get the effect of following another case's behavior while still getting compiler warnings for new cases.
-> @unknown은 알려진 사례와 일치하지 않는 열거형 값을 생성할 방법이 없고 만약 있다면 그것을 사용하는 안전한 방법이 없기 때문에 테스트할 수 없다는 단점이 있습니다. 그러나 fallthrough를 사용하여 @unknown을 다른 케이스와 결합하면 새로운 케이스에 대한 컴파일러 경고를 계속 받는 동안 다른 케이스의 동작을 따르는 효과를 얻을 수 있습니다.

switch excuse {
case .eatenByPet:
  showCutePicturesOfPet()

case .thoughtItWasDueNextWeek:
  fallthrough
@unknown default:
  askForDueDateExtension()
}

그래서. default랑 무엇이 다를까? 의 물음에 내가 이해한 답은

nonfrozen enum의 경우에 나중에 추가될 case에대해 warning을 띄워주는것이라고 이해했다.
(default로 넘긴다면 그냥 아무것도 안뜨고 잘 넘어간다.)
예제 코드에선 그래서 이 @unknown default의 경우에 새로운 case가 있다는걸 알리는(?) 함수를 써 주었더랬다.

profile
어제보다만 나아지는

0개의 댓글