从函数返回多个值的优雅方法

2024-09-25 02:35:43 发布

您现在位置:Python中文网/ 问答频道 /正文

似乎在大多数主流编程语言中,从函数返回多个值是一件非常尴尬的事情。

典型的解决方案是创建一个struct或一个普通的旧数据类并返回它,或者通过引用或指针传递至少一些参数,而不是返回它们。

使用引用/指针相当尴尬,因为它依赖于副作用,意味着您还有另一个参数要传递。

类/结构解决方案也非常尴尬,因为最终会有一百万个小类/结构,这些类/结构只用于从函数返回值,从而产生不必要的混乱和冗长。

而且,很多时候总是需要一个返回值,其余的只在某些情况下由调用者使用。这两种解决方案都不允许调用方忽略不需要的返回类型。

我所知道的处理多个返回值的一种语言是Python。对于不熟悉的人,它使用tuple解包:

a, b = foo(c)  # a and b are regular variables.
myTuple = foo(c)  # myTuple is a tuple of (a, b)

有没有其他好的办法来解决这个问题?除了Python和在非主流语言中看到的语言级解决方案之外,在现有主流语言中工作的这两种习惯用法都是受欢迎的。


Tags: 数据函数语言参数foo解决方案事情结构
3条回答

几乎所有受ML影响的函数式语言(其中大部分)都有强大的元组支持,这使得这类事情变得微不足道。

< C++ >我喜欢Boo::tuple加Booo::TIE(或者STD::Tr1,如果你有它)

typedef boost::tuple<double,double,double> XYZ;

XYZ foo();

double x,y,z;
boost::tie(x,y,z) = foo();

或是一个不那么做作的例子

MyMultimap::iterator lower,upper;
boost::tie(lower,upper) = some_map.equal_range(key);

一些语言,特别是Lisp和JavaScript,有一个称为destructuring assignment或destructuring bind的特性。这本质上是类固醇上的元组解包:您可以在赋值语句中解包更复杂的对象结构,而不局限于元组、列表或生成器等序列。有关详细信息,请参见here for the Lisp versionhere for the (rather more readable) JavaScript version

除此之外,我不知道通常处理多个返回值的许多语言特性。但是,多个返回值有一些特定的用法,这些用法通常可以被其他语言特性所替代。例如,如果其中一个值是错误代码,则最好将其替换为异常。

虽然创建新的类来保存多个返回值感觉很混乱,但同时返回这些值的事实往往表明,一旦创建了类,您的代码总体上将会更好。特别是,处理相同数据的其他函数可以移到新类中,这可能使代码更易于遵循。这并非普遍正确,但值得考虑。(Cpeterso关于数据块的回答更详细地表达了这一点)。

PHP示例:

function my_funct() {
    $x = "hello";
    $y = "world";
    return array($x, $y);
}

然后,运行时:

list($x, $y) = my_funct();
echo $x.' '.$y; // "hello world"

相关问题 更多 >