以scala为例
一,模式:数据结构上的模式,描述一个数据结构的组成
要理解模式匹配(pattern-matching),先把这两个单词拆开,先理解什么是模式(pattern),这里所的模式并不是设计模式里的模式,而是数据结构上的,这个模式用于描述一个结构的组成。
我们很容易联想到“正则表达”里的模式,不错,这个pattern和正则里的pattern相似,不过适用范围更广,可以针对各种类型的数据结构,不像正则表达只是针对字符串。比如正则表达式里"^A.*"这个pattern 表示以A开头、后续一个或多个字符组成的字符串;List("A", _, _*)也是个pattern,表示第一个元素是”A”,后续一个或多个元素的List。
狭义的看,模式可以当作对某个类型,其内部数据在结构上抽象出来的表达式。如上面的List("A", _, _*)就是一种List结构的pattern。模式匹配(pattern-matching)则是匹配变量是否符合这种pattern。比如List("A","B")和List("A","X","Y")就符合上面的pattern,而List("X")则不符合。
// 匹配一个数组,它由三个元素组成,第一个元素为1,第二个元素为2,第三个元素为3
scala> Array(1,2,3) match { case Array(1,2,3) => println("ok")} ok
// 匹配一个数组,它至少由一个元素组成,第一个元素为1 scala> Array(1,2,3) match { case Array(1,_*) => println("ok")} ok
// 匹配一个List,它由三个元素组成,第一个元素为“A",第二个元素任意类型,第三个元素为"C" scala> List("A","B","C") match{ case List("A",_,"C") => println("ok") } ok
例子中的:Array(1,2,3),List("A",_,"C")等都是模式,表示由指定元素组成的某种类型。
当然模式也不仅仅是表示某种结构的,还可以是常量,或类型,如:
scala> val a = 100 a: Int = 100 // 常量模式,
如果a与100相等则匹配成功 scala> a match { case 100 => println("ok") } ok // 类型模式,
如果a是Int类型就匹配成功 scala> a match { case _:Int => println("ok") } ok
在 scala里对pattern有明确的定义,在形式上有以下几种pattern:
1) 常量模式(constant patterns) 包含常量变量和常量字面量
scala> val site = "alibaba.com" scala> site match { case "alibaba.com" => println("ok") }
scala> val ALIBABA="alibaba.com" //注意这里常量必须以大写字母开头
scala> def foo(s:String) { s match { case ALIBABA => println("ok") } }
常量模式和普通的 if 比较两个对象是否相等(equals) 没有区别,并没有感觉到什么威力
2) 变量模式(variable patterns)
确切的说单纯的变量模式没有匹配判断的过程,只是把传入的对象给起了一个新的变量名。
scala> site match { case whateverName => println(whateverName) }
上面把要匹配的 site对象用 whateverName 变量名代替,所以它总会匹配成功。不过这里有个约定,对于变量,要求必须是以小写字母开头,否则会把它对待成一个常量变量,比如上面的whateverName 如果写成WhateverName就会去找这个WhateverName的变量,如果找到则比较相等性,找不到则出错。
变量模式通常不会单独使用,而是在多种模式组合时使用,比如
List(1,2) match{ case List(x,2) => println(x) }
里面的x就是对匹配到的第一个元素用变量x标记。
3) 通配符模式(wildcard patterns)
通配符用下划线表示:"_",可以理解成一个特殊的变量或占位符。
单纯的通配符模式通常在模式匹配的最后一行出现,case _ =>它可以匹配任何对象,用于处理所有其它匹配不成功的情况。
通配符模式也常和其他模式组合使用:
scala> List(1,2,3) match{ case List(_,_,3) => println("ok") }
上面的List(_,_,3)里用了2个通配符表示第一个和第二个元素,这2个元素可以是任意类型
通配符通常用于代表所不关心的部分,它不像变量模式可以后续的逻辑中使用这个变量。
//补充 摘自《ML程序设计教程》:
模式(pattern) 是一个只包含变量、构造子和通配符的表达式。构造子包括:
1) 数、字符和字符串常量。
2)序偶、元组和记录结构。
3)表和数据类型的构造子在模式中,所有不是构造子的名字都是变量。任何它们在模式之外可能拥有的意思都无效了。模式中的变量必须彼此不同。这些条件保证了值可以有效地和模式进行匹配,并且以唯一的方式通过分析绑定到变量上去
网友评论