From Swift 5, new case attribute @unknown
is introduced.
What is the exact difference when @unknown
is being used and not being used? In which case we have to use @unknown
keyword?
@unknown default case In Swift 5.0, a new @unknown keyword can be added to the default switch case. This doesn't change the behavior of default , so this case will still match any cases that aren't handled in the rest of the switch block.
If you want your switch statement fall through or you want C style fallthrough feature then you can use fallthrough statement. This statement is used to forcefully execute the case present next after the matched statement even though the case is not matching the specified condition.
The fallthrough keyword simply causes code execution to move directly to the statements inside the next case (or default case) block, as in C's standard switch statement behaviour.
Introduced with Swift 5, the @unknown attribute is particularly useful when switching over a nonfrozen enumeration. While the @frozen attribute is used on familiar enums such as Result or Optional within the standard library..
From SE-0192: Handling Future Enum Cases (emphasis mine):
When switching over a non-frozen
enum
, theswitch
statement that matches against it must include a catch-all case (usuallydefault
or an "ignore"_
pattern).switch excuse { case .eatenByPet: // … case .thoughtItWasDueNextWeek: // … }
Failure to do so will produce a warning in Swift 5. A program will trap at run time if an unknown enum case is actually encountered.
All other uses of enums (
if case
, creation, accessing members, etc) do not change. Only the exhaustiveness checking of switches is affected by the frozen/non-frozen distinction. Non-exhaustive switches over frozen enums (and boolean values) will continue to be invalid in all language modes.Here's a more complicated example:
switch (excuse, notifiedTeacherBeforeDeadline) { case (.eatenByPet, true): // … case (.thoughtItWasDueNextWeek, true): // … case (_, false): // … }
This switch handles all known patterns, but still doesn't account for the possibility of a new enum case when the second tuple element is
true
. This should result in a warning in Swift 5, like the first example.
@unknown
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.)
@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".The compiler will warn 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
has a downside that it is not testable, since there is no way to create anenum
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.switch excuse { case .eatenByPet: showCutePicturesOfPet() case .thoughtItWasDueNextWeek: fallthrough @unknown default: askForDueDateExtension() }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With