切换案例“@unknown default"之间的区别和“默认"在斯威夫特 5 [英] Difference between switch cases "@unknown default" and "default" in Swift 5
问题描述
从 Swift 5 开始,引入了新的 case 属性 @unknown
.
From Swift 5, new case attribute @unknown
is introduced.
@unknown
使用和不使用的确切区别是什么?在什么情况下我们必须使用 @unknown
关键字?
What is the exact difference when @unknown
is being used and not being used? In which case we have to use @unknown
keyword?
推荐答案
来自 SE-0192:处理未来的枚举案例(强调我的):
当切换一个非冻结的 enum
时,switch
语句表明匹配它必须包含一个包罗万象的情况(通常是 default
或忽略"_
模式).
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:
// …
}
如果不这样做将在 Swift 5 中产生警告.程序将如果实际遇到未知枚举情况,则在运行时捕获.
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.
枚举的所有其他用途(if case
、创建、访问成员等)不要换.只有开关的详尽检查是受冷冻/非冷冻区别的影响.非穷举开关在冻结枚举(和布尔值)将继续无效所有语言模式.
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):
// …
}
这个开关处理所有已知的模式,但仍然没有考虑当第二个元组元素是新的枚举情况的可能性真
.这应该会导致 Swift 5 中的警告,就像第一个一样示例.
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.
使用默认情况的缺点是编译器不能不再提醒开发人员特定枚举具有以下元素没有在 switch 中明确处理.为了解决这个问题,switch
case 将获得一个新属性,@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:
// …
}
与常规默认值一样,@unknown
默认值匹配任何值;这是一个包罗万象"的案例.但是,编译器会产生一个警告,如果尚未匹配枚举的所有已知元素.这是警告而不是错误,以便向枚举添加新元素仍然是与源兼容的更改.(这也是为什么@unknown 默认匹配任何值,而不仅仅是那些在编译时看不到的值.)
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
只能应用于默认或由单一模式_.即使在后一种情况下,也必须使用 @unknown
最后一个案例在一个开关中.此限制将进一步讨论在未来方向"下的未知模式"部分.
@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".
如果模式中的所有枚举都被匹配,编译器将发出警告@unknown 被明确注释为冻结,或者如果没有枚举在模式中.这是一个警告而不是一个错误,因此将枚举注释为冻结仍然是与源兼容的更改.如果该模式包含任何隐式冻结的枚举(即因为它是一个用户定义的 Swift 枚举),@unknown 是允许的,在以便更容易适应新增的案例.
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
有一个缺点,它不可可测试,因为有无法创建与任何已知情况不匹配的 enum
值,如果有的话,就不会有安全的使用方法.然而,将 @unknown
与其他使用 fallthrough 的情况结合起来可以得到遵循另一个案例的行为同时仍然得到的效果新案例的编译器警告.
@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.
switch excuse {
case .eatenByPet:
showCutePicturesOfPet()
case .thoughtItWasDueNextWeek:
fallthrough
@unknown default:
askForDueDateExtension()
}
这篇关于切换案例“@unknown default"之间的区别和“默认"在斯威夫特 5的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!