Swift可以对switch中不同数据类型的值作匹配判断:
var things = Any[]() things.append(0) things.append(0.0) things.append(42) things.append(3.14159) things.append("hello") things.append((3.0, 5.0)) things.append(Movie(name:"Ghostbusters", director:"Ivan Reitman")) for thing in things { switch thing { case 0 as Int: println("zero as an Int") case 0 as Double: println("zero as a Double") case let someInt as Int: println("an integer value of (someInt)") case let someDouble as Double where someDouble > 0: println("a positive double value of (someDouble)") case is Double: println("some other double value that I don't want to print") case let someString as String: println("a string value of "(someString)"") case let (x, y) as (Double, Double): println("an (x, y) point at (x), (y)") case let movie as Movie: println("a movie called '(movie.name)', dir. (movie.director)") default: println("something else") } } // zero as an Int // zero as a Double // an integer value of 42 // a positive double value of 3.14159 // a string value of"hello" // an (x, y) point at 3.0, 5.0 // a movie called 'Ghostbusters', dir. Ivan Reitman
这里面会根据thing的值进行匹配,到对应的case当中。
今天突然想到一个问题,让我觉得有必要总结一下switch语句。我们知道swift中的switch,远比C语言只能比较整数强大得多,但问题来了,哪些类型可以放到switch中比较呢,对象可以比较么?
官方文档对switch的用法给出了这样的解释:
Cases can match many different patterns, including interval matches, tuples, and casts to a specific type.
也就是说除了最常用的比较整数、字符串等等之外,switch还可以用来匹配范围、元组,转化成某个特定类型等等。但文档里这个including用的实在是无语,因为它没有指明所有可以放在switch中比较的类型,文章开头提出的问题依然没有答案。
我们不妨动手试一下,用switch匹配对象:
class A { } var o = A() var o1 = A() var o2 = A() switch o { case o1: print("it is o1") case o2: print("it is o2") default: print("not o1 or o2") }
果然,编译器报错了:“Expression pattern of type 'A' cannot match values of type 'A'”。至少我们目前还不明白“expression pattern”是什么,怎么类型A就不能匹配类型A了。
我们做一下改动,在case语句后面加上let:
switch o { case let o1: print("it is o1") case let o2: print("it is o2") default: print("not o1 or o2") }
OK,html" target="_blank">编译运行,结果是:it is o1。这是因为case let不是匹配值,而是值绑定,也就是把o的值赋给临时变量o1,这在o是可选类型时很有用,类似于if let那样的隐式解析可选类型。没有打出it is o2是因为swift中的switch,只匹配第一个相符的case,然后就结束了,即使不写break也不会跳到后面的case。
扯远了,回到话题上来,既然添加let不行,我们得想别的办法。这时候不妨考虑一下switch语句是怎么实现的。据我个人猜测,估计类似于用了好多个if判断有没有匹配的case,那既然如此,我们给类型A重载一下==运算符试试:
class A {} func == (lhs: A, rhs: A) -> Bool { return true } var o = A(); var o1 = A() ;var o2 = A() switch o { case o1: print("it is o1") case o2: print("it is o2") default: print("not o1 or o2") }
很显然,又失败了。如果这就能搞定问题,那这篇文章也太水了。报错信息和之前一样。可问题是我们已经重载了==运算符,为什么A类型还是不能饿匹配A类型呢,难道switch不用判断两个变量是否相等么。
switch作为一个多条件匹配的语句,自然是要判断变量是否相等的,不过它不是通过==运算符判断,而是通过~=运算符。再来看一段官方文档的解释:
An expression pattern represents the value of an expression. Expression patterns appear only in switch statement case labels.
以及这句话:
The expression represented by the expression pattern is compared with the value of an input expression using the Swift standard library ~= operator.
第一句解释了之前的报错,所谓的“express pattern”是指表达式的值,这个概念只在switch的case标签中有。所以之前的报错信息是说:“o1这个表达式的值(还是o1)与传入的参数o都是类型A的,但它们无法匹配”。至于为什么不能匹配,答案在第二句话中,因为o1和o的匹配是通过调用标准库中的~=运算符完成的。
所以,只要把重载==换成重载~=就可以了。改动一个字符,别的都不用改,然后程序就可以运行了。Swift默认在~=运算符中调用==运算符,这也就是为什么我们感觉不到匹配整数类型需要什么额外处理。但对于自定义类型来说,不重载~=运算符,就算你重载了==也是没用的。
除此以外,还有一种解决方法,那就是让A类型实现Equatable协议。这样就不需要重载~=运算符了。答案就在Swift的module的最后几行:
@warn_unused_result public func ~=<T : Equatable>(a: T, b: T) -> Bool
Swift已经为所有实现了Equatable协议的类重载了~=运算符。虽然实现Equatable协议只要求重载==运算符,但如果你不显式的注明遵守了Equatable协议,swift是无法知道的。因此,如果你重载了==运算符,就顺手标注一下实现了Equatable协议吧,这样还有很多好处,比如SequenceType的split方法等。
最后总结一句:
能放在switch语句中的类型必须重载~=运算符,或者实现Equatable协议。
本文向大家介绍Swift编程中的switch...case语句实例解析,包括了Swift编程中的switch...case语句实例解析的使用技巧和注意事项,需要的朋友参考一下 Swift中的switch...case语句可以判断对象类型, Objective-C中则必须是整数。 不可以穿透,可以不写break, 因为不能穿透所以不能这么写 只能这么写 不能不写default default位置只能
本文向大家介绍java中switch case语句需要加入break的原因解析,包括了java中switch case语句需要加入break的原因解析的使用技巧和注意事项,需要的朋友参考一下 java中switch case语句需要加入break的原因解析 java 中使用switch case语句需要加入break 做了具体的实例分析,及编译源码,在源码中分析应该如何使用,
问题内容: 我想知道是否有一种方法可以在java switch case语句中执行不区分大小写的匹配。默认实现 区分大小写 。请参见下面的示例。 因此,以上语句作为输出返回。而且我正在尝试使其像 不区分大小写的 匹配一样工作。我尝试将字符串文字都转换为小写,然后进行比较。但无法做到。 问题答案: 如果要这样做:只需确保输入数据全部为小写,并使用小写… 本地化问题 同样,古老的本地化问题再次引起人们
本文向大家介绍举例讲解Swift编程中switch...case语句的用法,包括了举例讲解Swift编程中switch...case语句的用法的使用技巧和注意事项,需要的朋友参考一下 Switch作为选择结构中必不可少的语句也被加入到了Swift中,只要有过编程经验的人对Switch语句都不会感到陌生,但苹果对Switch进行了大大的增强,使其拥有其他语言中没有的特性。使用Switch语句很简单:
问题内容: 我正在学习Swift的语法,想知道为什么下面的代码无法按我期望的那样工作: 我想每次将数字除以3(3、6、9、12等)时都打印Fizz,并且每次将其除以5时都打印Buzz,那么缺少哪一块拼图? 注意:我确实使用以下方法解决了问题: 我想知道如何使用Switch解决此问题。谢谢。 问题答案: FizzBuzz游戏的通常规则 是用“ Fizz”替换每个3的倍数,用“ Buzz”替换每个
本文向大家介绍详解Swift的switch...case语句中break关键字的用法,包括了详解Swift的switch...case语句中break关键字的用法的使用技巧和注意事项,需要的朋友参考一下 与Objective-C中这部分内容相比,在Swift中switch得到了极大的改善。这是一件非常有趣的事,因为这还是没有添加到Objective-C中,还是没有打破Objective-C是C的超