> (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
似乎想要匹配整个哈希表,而不仅仅是一个键值对。
最佳答案
如何复制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
,而不是局部变量。由于这种阴影,局部变量从未被实际使用过。
关于pattern-matching - 如何将哈希表与局部变量的值进行匹配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52250601/