분기: case
분기: case
case는 값의 결과에 따라 여러 분기 중 하나를 골라 실행하는 매칭 폼이에요. 값이 여러 리터럴 중 하나와 같은지 비교해서 분기를 선택하죠.
출처: Racket Reference
본문
3.13 분기: case
(case val-expr case-clause ...)
case-clause = [(datum ...) then-body ...+]
| [else then-body ...+]
val-expr을 평가하고 그 결과로 case-clause를 선택합니다. 선택되는 절(clause)은, 리터럴(datum)의 quoted 형태가 val-expr의 결과와 equal?인 절 중에서 첫 번째 절입니다. 그런 리터럴이 없으면 else 절이 선택되고, else 절도 없다면 case 폼의 결과는 #<void>입니다.
Racket의 case 폼은 R6RS나 R5RS의 case와 달리 eqv?가 아니라 equal?에 기반한다는 점에서 다릅니다 (내부 정의를 허용한다는 점도 추가로 다릅니다).
선택된 case-clause에서, case 폼에 대해 꼬리 위치(tail position)에 있는 마지막 then-body의 결과가 전체 case 폼의 결과입니다. else로 시작하는 절은 반드시 마지막 case-clause여야 합니다.
case 폼은 N개의 리터럴에 대해 O(log N) 시간에 일치하는 절로 분기할 수 있습니다.
예시:
> (case (+ 7 5)
[(1 2 3) 'small]
[(10 11 12) 'big])
'big
> (case (- 7 5)
[(1 2 3) 'small]
[(10 11 12) 'big])
'small
> (case (string-append "do" "g")
[("cat" "dog" "mouse") "animal"]
[else "mineral or vegetable"])
"animal"
> (case (list 'y 'x)
[((a b) (x y)) 'forwards]
[((b a) (y x)) 'backwards])
'backwards
> (case 'x
[(x) "ex"]
[('x) "quoted ex"])
"ex"
> (case (list 'quote 'x)
[(x) "ex"]
[('x) "quoted ex"])
"quoted ex"
(define (classify c)
(case (char-general-category c)
[(ll lu lt ln lo) "letter"]
[(nd nl no) "number"]
[else "other"]))
> (classify #\A)
"letter"
> (classify #\1)
"number"
> (classify #\!)
"other"
3.13.1 case의 변형들
(require racket/case)
package: base
이 섹션에 문서화된 바인딩들은 racket/case 라이브러리가 제공해요. racket/base나 racket이 제공하는 게 아니라는 점에 주의할게요.
Added in version 8.11.1.8 of package base.
(case/equal val-expr case-clause ...)
(case/equal-always val-expr case-clause ...)
(case/eq val-expr case-clause ...)
(case/eqv val-expr case-clause ...)
case와 같지만, case-clause의 리터럴과 val-expr의 결과를 비교할 때 equal?, equal-always?, eq?, 또는 eqv?를 사용합니다. case/equal 폼은 case와 동등합니다.