val tup = ("hello world", 42)
tup match {
case (s,i) =>
println("the string was " + s)
println("the number was " + i
}
有一个列表:
val xs = List(1,2,3,4,5,6)
xs match {
case h :: t =>
// h is the head: 1
// t is the tail: 2,3,4,5,6
// The :: above is also an example of matching with an INFIX TYPE
}
使用案例类
case class Person(name: String, age: Int)
val p = Person("John Doe", 42)
p match {
case Person(name, 42) =>
//only extracting the name here, the match would fail if the age wasn't 42
println(name)
}
C)模式匹配可以用于赋值和for-解析,而不仅仅是匹配块:
val tup = (19,73)
val (a,b) = tup
for((a,b) <- Some(tup)) yield a+b // Some(92)
scala> def badMatch(l: List[Int]): Unit = l match { case x :: xs => println(x) }
<console>:7: warning: match may not be exhaustive.
It would fail on the following input: Nil
def badMatch(l: List[Int]): Unit = l match { case x :: xs => println(x) }
^
badMatch: (l: List[Int])Unit
scala> badMatch(List(1, 2))
1
scala> badMatch(Nil)
scala.MatchError: List() (of class scala.collection.immutable.Nil$)
6条答案
按热度按时间m4pnthwp1#
首先我想指出的是,你没有使用模式匹配来“代替”switch语句,Scala没有
switch
语句,它有匹配块,匹配块中的大小写看起来非常类似于switch语句。使用模式匹配匹配块可以完成
switch
所做的一切,甚至更多。A)它不仅限于原语和Oracle在语言规范中选择“祝福”的其他类型(字符串和枚举)。如果你想匹配你自己的类型,那就去吧!
B)模式匹配也可以提取。例如,对于元组:
有一个列表:
使用案例类
C)模式匹配可以用于赋值和for-解析,而不仅仅是匹配块:
D)匹配块是表达式,而不是语句
这意味着它们只对匹配的大小写的主体求值,而不是完全通过副作用来执行。这对于函数式编程来说是至关重要的!
nom7f22z2#
不知何故,我对@KevinWright答案的编辑/添加被丢弃了,所以我将在这里添加它作为一个更好的模式匹配功能...
F)编译器对案例的详尽检查。
如果存在一个值匹配,而这个值不被现有的case覆盖,编译器会警告你,这是语言的一个非常好的特性,因为如果你不忽略这些编译器警告,你就不会捕捉到这样的运行时异常,或者遇到你没有想到的case。如果您仍然运行应用程序并忽略警告,则当您的值不匹配任何大小写时,您将获得一个很好的描述性异常。
在这种情况下,我更喜欢得到一个异常,因为它会失败得很清楚,而且通常会很早,而不是执行意外的逻辑分支。
如果你使用
if
,你就必须使用else
,如果你使用Javaswitch
,你就必须使用default
case来覆盖所有的情况。Scala编译器知道在这种情况下空列表和非空列表是不同的,或者更广义地说,你定义了匹配的粒度,你可以匹配1或2个元素的列表,忽略剩下的,或者使用其他更复杂的模式,而不必担心你是否能覆盖所有的情况。简而言之,当你使用复杂的提取和匹配逻辑时,编译器会确保你不会错过任何大小写。在Java中没有类似的情况,除非你使用默认的大小写,如
default
或else
。ni65a41a3#
模式匹配不是switch语句的替代方法,我认为它是在oop中执行动态调度的另一种方法。它们尝试做同样的事情:基于参数的动态类型调用函数的不同版本
lndjwyie4#
正如在其他答案中所写的,Scala模式匹配和Java开关并不是一回事。
switch语句:
模式匹配:
换句话说,你可以使用“模式匹配”来达到类似于“java开关”的目的,但是在这样做的时候,你是在以一种命令式的方式使用函数工具。
h7appiyu5#
JMPL是一个简单的java库,它可以使用Java 8特性模拟模式匹配的一些特性。
taor4pac6#
摘自Martin Odersky(Scala的创建者)和其他人的一本伟大的书Programming in Scala。
Java的
switch
case
中使用break
在每个备选项的末尾break
,从一个备选方案跌落到下一个备选方案*不产生值
Scala的
match
case
中可以使用任何类型的常量以及其他内容break
*产生一个值
示例使用Java和Scala编程的相同逻辑:
斯卡拉
java
Scala的
match
可以产生一个值,Java的switch
不能: