【问题标题】:Is there a way to access n-th returned value from a function returning `(values 1 2 3)` in Racket?有没有办法从 Racket 中返回 `(values 1 2 3)` 的函数访问第 n 个返回值?
【发布时间】:2015-05-25 03:52:42
【问题描述】:

给定一个这样的函数

(define (foo) (values 1 2 3))

我能否以某种方式调用(foo) 并且只获得其中一个值,例如(first (foo))?我想过为此定义一个辅助函数,但它必须与被调用函数的数量相匹配,这感觉不对。

(define (first x y z) x)
(first (foo))

【问题讨论】:

    标签: scheme lisp racket multiple-return-values


    【解决方案1】:

    嗯,简单的方法就是使用define-values 绑定所有三个值,然后忽略后两个。不过,这有点令人不满意。更好的解决方案可能是使用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 相同,但效率更高。

    【讨论】:

    • 通过设计?!他们不希望人们编写使用values的程序吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-08
    • 2021-11-09
    • 1970-01-01
    • 2021-07-02
    • 1970-01-01
    • 2021-09-19
    相关资源
    最近更新 更多