使用scala模式匹配而不是java switch case有什么好处?

每个人都说模式匹配是函数式语言的一个很好的特性。 为什么?

我不能简单地使用ifs和切换案例的一切吗?

我想了解使用模式匹配而不是常规过程编程ifs和switch case的优点

我首先要注意的是,你不使用模式匹配“代替”switch语句。 Scala没有switch语句,它所拥有的是匹配块,其中的表面看起来非常类似于switch语句。

具有模式匹配的匹配块可以完成switch所做的一切,等等。

A)它不仅限于Oracle在语言规范 (字符串和枚举)中选择“祝福”的原语和其他类型 。 如果您想要匹配自己的类型,请继续前进!

B)模式匹配也可以提取 。 例如,使用元组:

 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-comprehensions ,而不仅仅是匹配块:

 val tup = (19,73) val (a,b) = tup for((a,b) <- Some(tup)) yield a+b // Some(92) 

D)匹配块是表达式,而不是语句

这意味着他们会根据匹配的情况评估身体,而不是完全通过副作用来表现。 这对于函数式编程至关重要!

 val result = tup match { case (a,b) => a + b } 

不知何故,我对@KevinWright回答的编辑/添加被抛弃了,所以我将它添加到这里作为一个更好的模式匹配function…

F)编译器详尽检查案例。

如果存在与现有案例不涵盖的值匹配,编译器将向您发出警告。 这是该语言的一个非常好的function,因为如果您不忽略这些编译器警告,您将不会捕获此类运行时exception或遇到您没有想到的情况。 如果您仍然运行应用程序并忽略警告,那么如果您的值与任何情况都不匹配,您将获得一个很好的描述性exception。 这是一个例子:

 scala> def badMatch(l: List[Int]): Unit = l match { case x :: xs => println(x) } :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$) 

在这种情况下,我更喜欢得到一个例外,因为它会失败并且通常很早,而不是执行意外的逻辑分支。

如果您使用, if必须使用else ,并且如果使用Java switch ,则必须使用default情况来涵盖所有情况。 但请注意区别:在这种情况下,Scala编译器知道您的空列表与非空列表不同,或者更广泛地说,您定义匹配的粒度。 您可以将列表与1或2个元素匹配并忽略其余元素,或使用任何其他更复杂的模式,而不必担心是否设法涵盖所有​​情况。

简而言之,当您使用复杂的提取和匹配逻辑时,编译器将确保您不会错过任何情况。 除非你使用默认情况下的默认情况,否则Java中没有类似的else

模式匹配不是以某种方式替换switch语句 ,我认为它是在oop中进行动态分派的另一种方式。 他们尝试做同样的事情:根据参数的动态类型调用函数的不同版本

正如它在其他答案中所写的那样,Scala模式匹配和Java开关并没有做同样的事情。

开关声明:

  • 仅适用于本机类型,枚举类型和String类
  • 根据命令式编程,它是创建多个执行路径的“if-else”链的替代方案

模式匹配:

  • 它允许使用第一个匹配策略匹配任何类型的数据
  • 它符合一个function逻辑:每个case语句返回一个值,整个match语句实际上是一个返回匹配case值的函数。

换句话说,您可以使用“模式匹配”来实现“java开关”的类似目的,但这样做就是以命令的方式使用function工具。