我正在使用Racket和Dr. Racket进行教育。
我正在尝试了解values内置函数。
当我使用以下输入调用值时,我得到此输出:
> (values 'this 'and-this 'and-that)
'this
'and-this
'and-that
为什么这个测试失败了?
#lang racket
(require rackunit racket/trace)
(check-equal? (values 'this 'and-this 'and-that) 'this 'and-this 'and-that)
答案 0 :(得分:1)
由于values
正在返回multiple values,而check-equal?
无法处理,因此需要比较两个值。例如,这可行,因为我们只处理两个值:
(check-equal? (values 42) 42)
尝试不同的方法,我们先说我们首先解压缩多个值并将它们放在一个列表中:
(check-equal?
(let-values ([(a b c) (values 'this 'and-this 'and-that)])
(list a b c))
'(this and-this and-that))
答案 1 :(得分:1)
您可以将多个值转换为列表,然后将其与预期值进行比较:
(define-syntax values->list
(syntax-rules ()
((_ expr)
(call-with-values (lambda () expr)
list))))
(check-equal? (values->list (values 'this 'and-this 'and-that))
(list 'this 'and-this 'and-that))
values
非常特别。它与call-with-values
联系在一起。实际上它与list
和apply
几乎相同,但没有在两者之间创建缺点。因此只是一个优化。在使用堆栈的实现中,它将返回堆栈上的值,而call-with-values
将仅应用于应用thunk时获得的相同帧。
我认为Common Lisp版本更有用,因为它允许在单值的情况下使用多个值过程,只使用第一个值。在Scheme方言中,您需要使用call-with-values
或使用它的宏或过程来处理多个值,这些值不太灵活,但也许可以使其他调用稍微更有效。