- C-h f pcase
- docstring
- info:elisp#Pattern matching case statement
- manual
- Emacs: Pattern Matching with pcase
- 注意文中代码有几处有误
- Pattern Matching in Emacs Lisp – Wilfred Hughes::Blog
- 跟 cl-destructuring-bind, dash.el, shadchen.el 的比较
- EmacsWiki: Pattern Matching
- 一些例子
(pcase '(1 2 (4 . 5) "Hello")
(`(1 2 (4 . 5) ,(pred stringp))
(message "It matched!")))
(pcase '(a b c)
((and x (pred listp)) (message "Match List: %s" x)))
Notes that `(,_ . ,_)
match any cons cell, i.e., any list except nil
(pcase '(a b c)
('nil "Match nil (empty list)")
(`(,foo . ,bar)
(message "Match non-empty list with car = %s and cdr = %s" foo bar)))
By default, eq
is used for testing:
If a SYMBOL is used twice in the same pattern the second occurrence becomes an ‘eq’uality test.
(pcase '(1 1)
(`(,x ,x) (format-spec "Matching (%x %x) where %x eq %x" `((?x . ,x)))))
Here is an example of equal
(pcase '("1" "1")
(`(,x ,(and y (guard (equal x y))))
"Matching (%x %y) where %x equal %y"
(format-spec "Matching (%x %y) where %x equal %y"
`((?x . ,(pp-to-string x)) (?y . ,(pp-to-string y))))))
(pcase '(1 2 3)
(`(1 2 ,(and foo (let 3 foo)))
(message "A weird way of matching (1 2 3)")))
Fallback
(pcase-let (((or `(:key . ,val) (let val 42))
(cons :key 123)))
val)
(pcase-let (((or `(:key . ,val) (let val 42))
nil))
val)
(let (result)
(pcase-dolist (`(,k . ,v) '((one . 1) (two . 2) (three . 3)))
(push (list k v) result))
result)
当函数参数是一个 List 时,用 pcase-lambda 能够在参数表里分解它,类似 pcase-let。
(funcall
(pcase-lambda (`(,first ,second . ,rest))
(message "(%s %s . %s)" first second rest))
'(1 2 3 4 5))
Defined by seq.el so (require 'seq)
is required before using it.
List, vector, string are all sequences.
(pcase "hello"
((seq first second) (string first second)))
(pcase [1 2 3]
((seq first second) (list first second)))
(pcase " 42 "
((rx (* blank) (let result (1+ (in "0-9"))) (* blank))
result))
(pcase "a 1 2 3 3 2 1 b"
((rx (let x digit) space
(let y digit) space
(let z digit) space
(backref z) space
(backref 2) space
(backref 1) space)
(list x y z)))
(pcase-let ((`(,_ ,two ,_ ,four) '(1 2 3 4)))
(list two four))
(pcase-let ((`(,first . ,rest)
(number-sequence 1 100)))
(list first (apply #'+ rest)))
(pcase-let ((`(,a (,b (,c)))
'(1 (2 (3)))))
(list a b c))