Racket’s match
updated_at: 2022-02-27
说到Racket语言的match,其实它主是用于条件判断的,而谈到条件判断,在当代的编程语言中,最为大家熟知的莫过于if这个关键字了。当然Racket语言中也有if,但是其是最最基础的一个条件判断。其他诸如case、cond,亦或本文在后面即将铺展开来讲的match,尤其是match,在Racket语言的条件判断中,因为LISP语言高度同像性的S-expression语法,赋予其了非常多高阶使用方法。
|
1 从if谈起
2023年更正:
没有if-not的原因,更可能是因为(if-not a b c)总是可以被写成(if a c b)的,而其他的lisp方言有if-not,可能是因为他们的语言中,(if a b c)支持缺失c子句写成(if a b),而缺失子句在Racket中是被when覆盖了的:(when a b),而when是有when-not的,称为unless:(unless a c)。
很早时候,我就在官方文档读到过Choosing the Right Construct这个章节,但只是一略而过,认为没有什么特别大的价值。后来慢慢写的Racket代码多了,有几个关于let、if等几个索然无味的疑惑一直停留在脑海里,然后偶然重读了上面章节的文章才恍然大悟。
我在很长一段时间里面都在疑惑,Racket作为一个Scheme语言的流行方言,俨然已经是一个库非常丰富且成熟的语言了,为什么没有条件判断if关键字的否定判断关键字呢?因此在否定时都需要写成:
Like definitional constructs, conditionals come in many flavors, too. Because cond and its relatives (case, match, etc) now allow local uses of define, you should prefer them over if.
match在做条件判断时,其所能处理的维度远远胜过于if。这在上面提到的官方文档的Conditionals章节有更加明确的阐述和使用建议。
1.1 #:when/not/regexp在string对比中的使用
| ||||
> (define name "Yanying Wang") | ||||
; 写法1: | ||||
| ||||
Your family name is Wang | ||||
; 写法2: | ||||
| ||||
Your family name is Wang |
1.2 app在判断list长度中的使用
如上示例只是一些简单的条件判断,在我们要做更复杂的条件判断的时候,match的优势才会充分显示出来。
1.3 hash-table在hash键值对比中的使用
比如我们有一个HTTP的headers,其中有键值对Accept: application/json和Token: I am a racketeer,在Racket中以hasheq的数据结构存在,我们需要根据其值来做条件判断:
> (require racket/match) | |||||
> (define headers (hasheq 'Accept "application/json" 'Token "I am a racketeer")) | |||||
| |||||
correct Accept and Token detected | |||||
| |||||
[Accept: text/html] detected | |||||
| |||||
[Accept: app/html] detected | |||||
| |||||
unknown values |
2 示例:匹配一段字符串,相对应的去输出Xexpr进而转成HTML
我们需要从"大连市气象局发布大风红色预警[IV级/一般]"字符串中提取颜色,并且相对应的输出成HTML文档,比如是:<p class="sssubtext" style="color:Red">大连市气象局发布大风红色预警[IV级/一般]</p>。
2.1 使用cond的写法
> (require racket/match racket/string xml) | |||||||||||
| |||||||||||
> (gen-html "大连市气象局发布大风红色预警[IV级/一般]") | |||||||||||
"<p class=\"sssubtext\" style=\"color:Red\">大连市气象局发布大风红色预警[IV级/一般]</p>" |
2.2 使用match的#:when的写法
> (require racket/match racket/string xml) | |||||||||||
| |||||||||||
> (gen-html "大连市气象局发布大风红色预警[IV级/一般]") | |||||||||||
"<p class=\"sssubtext\" style=\"color:Red\">大连市气象局发布大风红色预警[IV级/一般]</p>" |
2.3 使用match的regexp的写法
> (require racket/match racket/string xml) | |||||||||||
| |||||||||||
> (gen-html "大连市气象局发布大风红色预警[IV级/一般]") | |||||||||||
"<p class=\"sssubtext\" style=\"color:Red\">大连市气象局发布大风红色预警[IV级/一般]</p>" |
2.4 使用match的app的写法
> (require racket/match racket/string xml) | |||||||||||
| |||||||||||
> (gen-html "大连市气象局发布大风红色预警[IV级/一般]") | |||||||||||
"<p class=\"sssubtext\" style=\"color:Red\">大连市气象局发布大风红色预警[IV级/一般]</p>" |