case和match之间有什么区别?

时间:2018-12-06 10:36:32

标签: match case racket

我对matchcase之间的区别感到困惑。在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。是真的吗除此之外有什么区别吗?

2 个答案:

答案 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)

有两个区别:

  1. matchcase强大得多。 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永远不会发生这种情况。

  1. case分支问题每个分支具有多个基准。

这些基准必须用括号括起来。

(case expr
  [(datum ...) answer]
  ...)

match的每个分支只有一个模式(没有括号)

(match expr
  [pattern answer]
  ...)