scheme - 有没有办法从 Racket 中返回 `(values 1 2 3)` 的函数访问第 n 个返回值?

标签 scheme lisp racket multiple-return-values

给定这样一个函数

(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只返回 quotientremainder 的值,但由于它是在单个函数中完成的,因此可以更有效地实现。同样,split-at与同时调用 takedrop 相同,但效率更高。

关于scheme - 有没有办法从 Racket 中返回 `(values 1 2 3)` 的函数访问第 n 个返回值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29188540/

相关文章:

list - 附加列表以显示在 Racket 的文本字段中

list - 以 "overlapped"的方式向列表添加值

scheme - Racket /方案: How to avoid repeating function call in cond

scheme - Guile计划-引用期间?

Lisp Web 框架?

macros - 在 emacs lisp 中定义 let 宏作用域

lambda - 为什么这个 racket 函数需要一个参数?它是如何工作的?

scheme - 在 Scheme 中,普通的、未引用的列表是否有语法糖?

scheme - 帮助理解 Scheme 中的 Continuations

cLISP 中的列表操作