给定这样的功能
(define (foo) (values 1 2 3))
我可以以某种方式调用(foo)
并且只获得其中一个值,例如(first (foo))
?我想过为此定义一个辅助函数,但它必须与被调用函数的数量相匹配,这感觉不对。
(define (first x y z) x)
(first (foo))
给定这样的功能
(define (foo) (values 1 2 3))
我可以以某种方式调用(foo)
并且只获得其中一个值,例如(first (foo))
?我想过为此定义一个辅助函数,但它必须与被调用函数的数量相匹配,这感觉不对。
(define (first x y z) x)
(first (foo))
好吧,简单的方法就是使用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
只返回 and 的值quotient
,remainder
但由于它是在单个函数中完成的,因此可以更有效地实现。同样,split-at
与调用take
and相同drop
,但它也更有效。