> (define h #hash((a . 11) (b . 0)))
> (define (f h key)
(match h
[(hash-table (key value)) value]
[_ 'do-something-else]))
> (f h 'a)
'do-something-else ;; expect 11
如何修改match
模式,使上面的函数返回与(hash-ref h key 'do-something-else)
相同的内容?
一个问题似乎是match
自动引用了key
,因此它实际上匹配'key
而不是局部变量key
的值。第二个问题是match hash-table
似乎要匹配整个哈希表,而不是仅一个键值对。
答案 0 :(得分:1)
hash-ref
的行为要复制hash-ref
的行为,您需要做两件事:
(1)使用key
模式,该模式仅将与参数key
的值等于相等的内容匹配。您可以使用==
pattern:
(hash-table ((== key) value))
(2)匹配哈希表,其中存在除key
以外的其他条目。您可以通过添加_ ...
使其与其他条目匹配来实现此目的。
(hash-table ((== key) value) _ ...)
在上下文中:
(define (f h key)
(match h
[(hash-table ((== key) value) _ ...) value]
[_ 'do-something-else]))
使(f h key)
的行为类似于(hash-ref h key 'do-something-else)
。
您的模式:
(hash-table (key value))
不自动对key
进行引号,使其与'key
完全匹配。相反,它匹配任何只有一个条目的哈希表:
> (match (hash 'anything-goes 11)
[(hash-table (key value)) value]
[_ 'do-something-else])
11
这是因为key
被解释为模式,而标识符作为模式可以匹配任何内容。如果将其命名为其他名称并在体内使用,则可以更清楚地看到这一点:
> (define (f h key-arg)
(match h
[(hash-table (key-pat value))
(printf "key-arg = ~v\n" key-arg)
(printf "key-pat = ~v\n" key-pat)
value]))
> (f (hash 'anything-goes 11) 'a)
key-arg = 'a
key-pat = 'anything-goes
11
当您编写一个标识符模式“碰巧”与本地变量具有相同的名称时,它会遮盖,就像下面的示例一样:
> (let ([x "local variable"])
(match (list 1 2 3)
[(list 1 2 x)
x]))
3
模式中的x
匹配任何内容,因此它与3
匹配。该模式遮盖了x
,因此当主体使用x
时,它是指3
,而不是局部变量。由于存在阴影,实际上从未使用过本地变量。