Ios Swift中开关箱的穷举条件
苹果说 每个switch语句都必须是详尽的。也就是说,一切可能 所考虑的类型的值必须与以下值之一匹配: 开关箱 所以在新的Xcode中,我放置了如下代码Ios Swift中开关箱的穷举条件,ios,swift,Ios,Swift,苹果说 每个switch语句都必须是详尽的。也就是说,一切可能 所考虑的类型的值必须与以下值之一匹配: 开关箱 所以在新的Xcode中,我放置了如下代码 println(UInt16.min); // Output : '0' println(UInt16.max); // Output : '65535' var quantity : UInt16 = 10; switch quantity { case 0...65535: //OR case UInt16.min...UInt16.m
println(UInt16.min); // Output : '0'
println(UInt16.max); // Output : '65535'
var quantity : UInt16 = 10;
switch quantity {
case 0...65535: //OR case UInt16.min...UInt16.max:
println();
default:
println();
}
现在,如果删除默认部分,则会出现编译器错误:
开关必须是详尽的是否要添加丢失的案例?修理
因此,我的问题是针对我提到的案例0…65535:我没有提到
UInt16
的所有案例值吗??但我还是犯了一个错误??为什么我会出现这个错误,我是否遗漏了一些东西???部分原因是编译器无法在不运行代码的情况下验证开关是否完整。表达式0…65535
创建一个ClosedInterval
struct,当switch语句执行时,它必须询问该struct值quantity
是否在间隔内。这在运行时有更改的空间,因此编译器无法在编译时检查它。(见附件。)
更一般地说,编译器无法检测整数值的穷举开关-即使您为每个整数值添加特定的案例(case 0:…case 1:…case 65535:
),它也不知道您的开关是穷举的。(理论上说,它可以:如果你想看的话,考虑一下这个问题)
目前,Swift可以在两种情况下检测完整性,并允许您省略default
子句:元组中的枚举和值绑定@NateCook的答案涵盖了枚举-如果您打开一个枚举值,并且在开关中为枚举中的每个案例都有一个案例
,则不需要默认值
。如果打开元组并绑定所有可能的值组合,则也不需要默认值标签,如图所示:
您可以将此规则概括为“如果类型系统知道您的类型的可能值,它可以检测开关
完整性”,但事实上存在一个级别,类型系统不知道可能值的范围(例如)UInt32
值有点像分裂的头发…Swift只会在使用enum
类型时真正验证开关
块是否详尽无遗。除了true
和false
之外,即使打开Bool
也需要default
块:
var b = true
switch b {
case true: println("true")
case false: println("false")
}
// error: switch must be exhaustive, consider adding a default clause
但是,对于枚举
,编译器只愿意查看以下两种情况:
enum MyBool {
case True
case False
}
var b = MyBool.True
switch b {
case .True: println("true")
case .False: println("false")
}
如果为了编译器需要包含一个default
块,但是没有任何事情可以做,那么break
关键字很方便:
var b = true
switch b {
case true: println("true")
case false: println("false")
default: break
}
Swift 4.1。您需要指定所有情况,或者只在switch语句中包含默认块。(从Swift 4.2开始,可能更早):我有一个帮助函数,用于将带有2个段的UISegmentedControl的Bool?
转换为selectedSegmentIndex
。如果该值为nil
,则不应选择任何一段。我的函数使用一个开关,它返回正确或错误值的适当段索引,并使用该开关显式测试nil
,以满足编译器对其穷举性的要求:
case nil: // only remaining possible value
fallthrough
default:
return UISegmentedControl.noSegment
从技术上讲,不需要使用案例nil:
故障诊断
,因为默认值:
就足够了,但是如果您想显式测试一个值以使代码更易于自我记录,则此语法可能很有用,或者在另一种情况下。检查您的枚举是否被初始化为可选的,可以是大小写,也可以是零。否…使用UInt8
尝试,它会提示您添加一个默认大小写,即使是所有256个数字。嗯,这就是我从手机中发布的内容,并且我忘记了一半。:)编辑了答案,并提供了更正和一些进一步的信息。“编译器无法在不运行代码的情况下验证开关是否完整”-这根本不是真的。第三种情况在没有default
的情况下可以工作。如果true
和false
都包含在内,则开关在Bool
上不需要默认情况。所以你的意思是iOS说它是详尽的,但实际上不是?我只是用一个非可选Bool体验了这一点,并认为我遗漏了一些东西。我提交了一份错误报告:19582311开关
不再需要默认
用于Bool
,如果您有真
和假
的案例。我不确定这一变化是什么时候发生的,但在Xcode 7.3中使用Swift 2.2时,上述功能可以正常工作。@NateCook。刚刚在xCode 10上检查过,如果存在true和false,则Bool不需要默认值。“错误:开关必须详尽”未确认;这个答案在Swift中不再正确。我怀疑是因为Swift 2或3。这段代码使用Xcode 7.3/Swift 2.2编译,因此编译器变得更智能:)。。。但它在运行时崩溃:(
case nil: // only remaining possible value
fallthrough
default:
return UISegmentedControl.noSegment