12模式匹配
match表支持对任意Racket值的模式匹配,而不是像regexp-match那样的函数,将正则表达式与字符及字节序列比较(参见《正则表达式》(Regular Expressions))。
match表获取target-expr的结果并试图按顺序匹配每个pattern。一旦它找到一个匹配,对相应的expr序列求值以得到匹配(match)表的结果。如果pattern包括模式变量(pattern variables),他们被当作通配符,并且在expr里的每个变量被绑定给的被匹配的输入片段。
大多数Racket的字面表达式可以用作模式:
'two
'no
'string
像cons、list和vector这样的构造器,可以用于创建模式,以匹配pairs、lists和vectors:
'two
'pair
'vector
用struct绑定的构造器也可以用作一个模式构造器:
"top"
不带引号的,在一个模式中的非构造器标识符是模式变量(pattern variables),它在结果表达式中被绑定,除了_,它不绑定(因此,这通常是作为一个泛称):
2
3
23
'something-else
省略号,写作...就像在一个列表或向量模式中的一个Kleene star:前面的子模式可以用于对列表或向量元素的任意数量的连续元素的任意次匹配。如果后跟省略号的子模式包含一个模式变量,这个变量会匹配多次,并在结果表达式里被绑定到一个匹配列表中:
'ones
'other
'(2 3)
45
省略号可以嵌套以匹配嵌套的重复,在这种情况下,模式变量可以绑定到匹配列表中:
'((1) (2 2) (3 3 3))
quasiquote表(见《准引用:quasiquoteand‘》获取更多关于它的信息)还可以用来建立模式。而一个通常的quasiquote表的unquoted部分意味着普通的racket求值,这里unquoted部分意味着回到普通模式匹配。
因此,在下面的例子中,with表达模式是模式并且它被改写成应用表达式,在第一个例子里用quasiquote作为一个模式,在第二个例子里quasiquote构建一个表达式。
'((lambda (x) (+ x 1)) 1)
有关更多模式表的信息,请参见《racket/match》。
像match-let表和match-lambda表支持位置模式,否则必须是标识符。例如,match-let概括let给一个破坏绑定(destructing bind):
'(3 2 1)
有关这些附加表的信息,请参见《racket/match》。
领取专属 10元无门槛券
私享最新 技术干货