给定这样一个函数
(define (foo) (values 1 2 3))
我能否以某种方式调用 (foo)
并只获取其中一个值,例如 (first (foo))
?我考虑过为此定义一个辅助函数,但它必须与被调用函数的元数相匹配,这感觉不对。
(define (first x y z) x)
(first (foo))
最佳答案
好吧,简单的方法就是使用 define-values
绑定(bind)所有三个值,然后忽略后两个。不过,这有点不令人满意。更好的解决方案可能是使用 match-define-values
,这将允许您明确忽略其他两个。
(match-define-values (a _ _) (values 1 2 3))
不过,这并不能真正让您将一个返回多个值的函数包装在另一个函数中以获得第一个值。
Racket 并没有真正提供很多用于操作多个值的内置工具,这实际上是设计使然。其他包可能包含您想要的功能——例如,sugar
包提供了 values->list
.
(first (values->list (values 1 2 3)))
这不在核心库中是有原因的:它是一种反模式。从一个函数返回多个值是你应该谨慎做的事情。 Racket 中返回多个值的函数并不多,因为它们使程序更难推理。它们组合得不好,而且很少能成为问题的最佳解决方案。
在某些情况下,多个返回值很有用,通常是在出于性能原因编写同时执行两件事的函数时。例如,quotient/remainder
只返回 quotient
和 remainder
的值,但由于它是在单个函数中完成的,因此可以更有效地实现。同样,split-at
与同时调用 take
和 drop
相同,但效率更高。
关于scheme - 有没有办法从 Racket 中返回 `(values 1 2 3)` 的函数访问第 n 个返回值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29188540/