我对match
和case
之间的区别感到困惑。在document中,它提到match
支持常规模式匹配。
> (define (m x)
(match x
[(list a b c)
#:when (= 6 (+ a b c))
'sum-is-six]
[(list a b c) 'sum-is-not-six]))
> (m '(1 2 3))
'sum-is-six
> (m '(2 3 4))
'sum-is-not-six
对于这个例子,我想我可以使用case
表达式来重写它。但是似乎很复杂。我必须获取输入x
的长度,也许还需要一个lambda函数来获取x
元素的总和并将其与6
进行比较。
所以我想我们在进行模式匹配时更喜欢match
。是真的吗除此之外有什么区别吗?
答案 0 :(得分:3)
您自己说的,match
的用法一般为pattern matching(一个非常强大的概念!),而case
仅检查某个值是否属于多个可能列表中的一个(隐式引用)价值观。 case
所做的只是为具有多个条件的cond
的语法糖,例如:
(case (+ 7 5)
[(1 2 3) 'small]
[(10 11 12) 'big]
[else 'other])
...大致等同于:
(let ((val (+ 7 5)))
(cond ((or (equal? val 1) (equal? val 2) (equal? val 3))
'small)
((or (equal? val 10) (equal? val 11) (equal? val 12))
'big)
(else 'other)))
match
进行一些复杂的匹配;它检查一个值是否是几种可能的 patterns 之一,这不仅是为了比较是否相等,还可以根据该模式检查该值的类型和“形状”,甚至可以添加其他值使用#:when
的约束。要了解可以在match
的{{3}}的语法部分下进行检查,多么复杂。
答案 1 :(得分:1)
有两个区别:
match
比case
强大得多。 case
没有match
那样的“模式”,它隐式地引用了每个“分支问题”中的基准。它仅将基准的引用形式与值进行比较,就像switch语句一样。 match
具有另一种更丰富的模式语言。这两个示例的每个分支问题中的x
(case 5
[(x) 10]
[else 'fail])
;=> 'fail
(case 'x
[(x) 10]
[else 'fail])
;=> 10
隐式引用为符号'x
。在匹配条件下,这等同于
(match 5
['x 10]
[_ 'fail])
;=> 'fail
(match 'x
['x 10]
[_ 'fail])
;=> 10
在哪里引用是创建模式的许多选项之一,而不是默认选项。如果您在match
中省略引号,则x
不再是符号;这是一个通配符,可匹配任何内容并定义x
作为结果。
(match 5
[x (+ x 1)])
;=> 6
由于case
的隐式引号,case
永远不会发生这种情况。
case
分支问题每个分支具有多个基准。这些基准必须用括号括起来。
(case expr
[(datum ...) answer]
...)
match
的每个分支只有一个模式(没有括号)
(match expr
[pattern answer]
...)