希望通过本文的标题,可以清楚地看出我不是在问Swift是否支持Switch语句,而是在问Swift是否支持Switch***表达式***,类似于C#所拥有的。
两者的区别很微妙,但却很重要。Switch语句是一种基于特定大小写对代码行进行分组的方法。而Switch表达式***则返回一个基于特定大小写的值。
假设您有以下枚举...
enum SomeEnum {
case a
case b
case c
}
现在假设你需要基于特定的switch语句计算/返回某个值。目前,在Swift中你必须使用Switch语句来完成这件事...
let someEnumValue: SomeEnum = .a
let result: String
switch someEnumValue {
case .binary: result = "This is the 'A' type"
case .octal: result = "This is the 'B' type"
case .hexadecimal: result = "This is the 'C' type"
}
print(result)
//prints 'This is the 'A' type'
如上图所示,在Swift中,你必须先声明let result: String
,但 * 不 * 给予它赋值,然后在Switch * 语句 * 中赋值,这是因为Switch * 语句 * 不返回值,它只基于匹配的case/condition执行代码。(是的,你也可以把所有这些放在一个函数中,然后简单地调用它,但这与这个问题是分开的。)
C#开关表达式
与此相反,下面是如何用C#编写它,并使用Switch表达式...
var result = someEnum switch {
SomeEnum.a => "This is the 'A' type",
SomeEnum.b => "This is the 'B' type",
SomeEnum.c => "This is the 'C' type"
}
Console.WriteLine(result)
//prints 'This is the 'A' type'
正如您在这里看到的,由于Switch表达式返回值,因此Switch表达式直接将值赋给result
变量。
注意:与Switch语句中单词“switch”位于变量之前不同,在Switch表达式中,单词switch位于变量 * 之后 *。此外,在大括号中,各个大小写用逗号分隔。最后,每个大小写只能是一个生成值的表达式。除非先将它们 Package 在自己的函数中,否则不能运行复合语句。
带闭包的伪版本
我的一个同事提出了这个方法,它使用了一个就地闭包。它稍微好一点,但是仍然没有真正的Switch表达式那么简单...
let result = {
switch someEnum {
case .a: return "This is the 'A' type"
case .b: return "This is the 'B' type"
case .c: return "This is the 'C' type"
}
}()
print(result)
所以我的问题很简单... Swift支持Switch表达式吗?如果不支持,让我们都向Swift.org推荐它,因为它让事情变得更容易/更简单!
1条答案
按热度按时间l0oc07j21#
自从回答了这个问题之后,已经有了将
if
和switch
表达式以SE-0380:if
andswitch
expressions(即accepted on 2022-01-20)的形式添加到该语言的运动。可以在apple/swift#62178上查看该实现,PR包括一个可下载的工具链,但该特性尚未在Swift的发布版本中登陆。我会尝试更新这个答案再次一旦该功能使它成为一个航运版本的斯威夫特。
最初的答案是为后代保留如下:
不幸的是,Swift没有
switch
表达式,只有switch
语句。Swift语言语法目前支持以下表达式:self.<whatever>
、self[<whatever>]
等)super.<whatever>
、super[<whatever>]
等)self
的函数或变量的引用,但基于上下文,允许跳过引用self
-例如,foo(123)
与self.foo(123)
相对)_
)请注意,控制流语句、
do
语句和其他语句不包括在此列表中-Swift只允许将这些语句作为完整语句。if
/guard
/switch
)label: <some statement>
)break
、continue
等)#if ...
、#error
、#warning
等)这是目前与语言核心紧密相连的东西,所以改变它将是一个不小的壮举!出于这个原因,这个特性也在控制流的Swift "通常拒绝的更改"列表的顶部:
if
/else
andswitch
as expressions:这些都是概念上有趣的支持,但通过将它们转换为表达式解决的许多问题在Swift中已经通过其他方式得到了解决。将它们转换为表达式会带来重大的权衡,总的来说,我们还没有找到一个明显优于我们目前所拥有的设计。尽管如此,这是论坛上定期出现的问题,并已得到广泛讨论(例如If / else expressions,其中也包含了很多关于
switch
表达式的讨论)。这是很多人想要的东西,所以我建议通过阅读论坛上的一些帖子来了解事物的最新状态,以获得关于什么/如何建设性地提出建议的想法,如果你感兴趣的话!