• scala pattern matching


    scala语言的一大重要特性之一就是模式匹配。在我看来,这个怎么看都很像java语言中的switch语句,但是,这个仅仅只是像(因为有case关键字),他们毕竟是不同的东西,switch在java中,只能是用在函数体类的,且需要结合break使用。但是,在scala语言中,pattern matching除了有case关键字,其他,似乎和java又有很多甚至完全不同的东西。

    scala在消息处理中为模式匹配提供了强大的支持!

    下面看看模式匹配的英文定义:

    A pattern match includes a sequence of alternatives, each starting with the keyword case. Each alternative includes a pattern and one or more expressions, which will be evaluated if the pattern matches. An arrow symbol => separates the pattern from the expressions. 

    再来给个简单的例子吧:

     1 package lession3
     2 
     3 object MyPattern {
     4    def main(args: Array[String]) {
     5       println(matchTest(3))
     6 
     7    }
     8    def matchTest(x: Int): String = x match {
     9       case 1 => "one"
    10       case 2 => "two"
    11       case _ => "many"
    12    }
    13 }

    上面的例子,case部分,是不是很像java中switch语句中的case?下面给个对应的简单的java例子:

     1 package com.shihuc.java;
     2 
     3 public class MySwitch {
     4     public static void main(String args[]){
     5         System.out.println(matchTest(3));
     6     }
     7     
     8     public static String matchTest(int x){
     9         String ret = "";
    10         switch(x){
    11         case 1: 
    12             ret = "one";
    13             break;
    14         case 2:
    15             ret = "two";
    16             break;
    17         default:
    18             ret = "many";
    19             break;
    20         }
    21         return ret;
    22     }
    23 }

    呵呵,是不是发现了相识和差异?都是一个模式对应一系列的候选可能表达(expressions,其实,就是一系列的处理过程),scala里面的case语句没有java switch中的break,scala里面的下划线_对应于java switch中的default,还有,是不是觉得那个x match很像java代码中的switch(x),当然了,学习一种语言,可以这么类比着学习!至少我是这么学的!

    另外,java的switch语句中的x是数值类型(int或者enum)的参数,但是,scala中,是没有这么要求的!任意类型都可以,这个是不是很强大?

     1 object Test {
     2    def main(args: Array[String]) {
     3       println(matchTest("two"))
     4       println(matchTest("test"))
     5       println(matchTest(1))
     6 
     7    }
     8    def matchTest(x: Any): Any = x match {
     9       case 1 => "one"
    10       case "two" => 2
    11       case y: Int => "scala.Int"
    12       case _ => "many"
    13    }
    14 }

    还有,scala的模式匹配书写格式,还可以如下这样:

     1 object Test {
     2    def main(args: Array[String]) {
     3       println(matchTest("two"))
     4       println(matchTest("test"))
     5       println(matchTest(1))
     6 
     7    }
     8    def matchTest(x: Any){
     9       x match {          //此处的x match关键部分,不再写在函数名称后面了,而是写在了函数体里面,即在函数块{}括号里面!
    10          case 1 => "one"
    11          case "two" => 2
    12          case y: Int => "scala.Int"
    13          case _ => "many"
    14       }
    15    }
    16 }

    再者,scala还支持模式匹配类,即在正常class定义中加入关键字case, 看下面的例子:

     1 object Test {
     2    def main(args: Array[String]) {
     3        val alice = new Person("Alice", 25)
     4        val bob = new Person("Bob", 32)
     5        val charlie = new Person("Charlie", 32)
     6    
     7       for (person <- List(alice, bob, charlie)) {
     8          person match {
     9             case Person("Alice", 25) => println("Hi Alice!")
    10             case Person("Bob", 32) => println("Hi Bob!")
    11             case Person(name, age) =>
    12                println("Age: " + age + " year, name: " + name + "?")
    13          }
    14       }
    15    }
    16    // case class, empty one.
    17    case class Person(name: String, age: Int)
    18 }

    case关键字将会促使scala编译器为Person类自动加入一些模式匹配的特性。

    首先,自动将Person类的参数类型转换为不可变(immutable)类型(即val,注意,val是可选的,此时);若想用可变的参数,则需要显示表明参数类型为var。

    其次,编译器自动将为Person类添加了例如equalshashCode,以及toString等class方法,我们不需要自己再写相关的方法了。

    scala的异常处理,也会涉及到case的使用,即各种细分的异常的模式匹配。这个与java中的try/catch()之多个catch()体不同:

    JAVA try catch:

     1 package com.shihuc.java;
     2 
     3 import java.io.FileNotFoundException;
     4 import java.io.FileReader;
     5 import java.io.IOException;
     6 
     7 public class FileOpen2 {
     8 
     9     public static void main(String args[]){
    10         try {
    11             FileReader fr = new FileReader("./test.txt");
    12             char buf[] = new char[1024];
    13             while(fr.read(buf) >= 0){
    14                 System.out.println(buf);
    15             }
    16         } catch (FileNotFoundException e) {
    17             // TODO Auto-generated catch block
    18             e.printStackTrace();
    19         } catch (IOException e) {
    20             // TODO Auto-generated catch block
    21             e.printStackTrace();
    22         }
    23     }
    24 }

    Scala try catch:

     1 import java.io.FileReader
     2 import java.io.FileNotFoundException
     3 import java.io.IOException
     4 
     5 object Test {
     6    def main(args: Array[String]) {
     7       try {
     8          val f = new FileReader("input.txt")
     9       } catch {
    10          case ex: FileNotFoundException =>{
    11             println("Missing file exception")
    12          }
    13          case ex: IOException => {
    14             println("IO Exception")
    15          }
    16       }
    17    }
    18 }
  • 相关阅读:
    javascript动态添加删除表格
    用C#使用HttpWebRequest Post数据时如何保持Session
    embed 元素的用法
    Ylmf Linux Y1.15(Ubuntu)发行版正式发布
    使用HttpWebRequest提交ASP.NET表单并保持Session和Cookie
    开3389后不能登录的六种原因
    ASP.NET无限级分类的实现
    深入理解JavaScript函数
    php 简明语法
    PainTwon:Linux开源的2D格斗游戏
  • 原文地址:https://www.cnblogs.com/shihuc/p/5081627.html
Copyright © 2020-2023  润新知