为什么某些流行语言中的函数只返回一种类型的结果?

时间:2010-07-16 07:05:55

标签: function memory syntax stack stack-trace

为什么某些流行语言中的函数只返回一种结果?

即我的意思是为什么编译器会给出以下语法错误

public int int  returnTwoIntegers(){
.......
........
}

13 个答案:

答案 0 :(得分:22)

函数只返回一个值,因为它是“他们”在汇编程序的旧时代发明它的方式。基本上发生的是该函数在堆栈上推送返回值。然后,调用者从堆栈中弹出值。如果函数返回更多值,则调用者不会知道要弹出多少个值,并且堆栈将是不平衡的(导致程序崩溃)。

答案 1 :(得分:18)

功能(您在代码中提到的语言)确实只有一个输出,但该输出不必是一个。您的输出可以很容易地成为一个封装您想要的任何数据量的类。

另请注意,您还可以将多个输入参数通过引用传递给您的函数,从而增加返回的输出数量。

答案 2 :(得分:10)

简化事项。

您始终可以使用这些语言返回T[]Pair<L,R>Set<E>等来模拟返回的多个值。这样可以处理大多数return值的场景。

为了获得如此少的收益,不值得改变语言的语义。

相关问题

答案 3 :(得分:6)

我最好的猜测是它从数学中延续下来。在那里你可以有一个带有多个参数的函数,并且值就是结果。

f(x1, x2, ...) = y (the formula might be something like x1 + x2^2 + x3^3 + ...)

即使您想将多维域映射到多维范围,通常也会写为:

f1(x1, x2, ...) = y1 (perhaps y1 = x1 + x2^1 + ... like above)
f2(x1, x2, ...) = y2 (and y2 = x1 - x2^2 + x3^3 - x4^4 +...)
...

因为每个y都根据输入得到它自己的数学公式,在编程中它只会转换为多个函数,所以将它分开是有意义的。

问题有时候y1和y2的公式可能非常相似,或者依赖迭代相同的东西或其他东西,将它们放在一起可能更有意义。在python中你可以做到

返回a1,a2;

然后将其称为

x,y = f();

但在大多数语言中,您只能返回一个变量。这并不能阻止你将它变成一个包含多个值的复杂对象。

答案 4 :(得分:2)

Google的Go支持多个return values

答案 5 :(得分:2)

Daniel Weinreb--曾使用Lisp方言(有多个返回值)和Java(没有),explains why

  

当我们将多值返回特性添加到Lisp机器Lisp(从那里进入Common Lisp)时,我相信避免消耗的愿望是一个严重的动机。那时候,我们没有很好的GC技术,而且编写Lisp程序来仔细地减少使用是很常见的。

     

另一个原因是表达性:明确表示该函数实际上返回的是多个结果,而不是引入一个小的“类型”列表(例如“文件句柄的两个列表和一个布尔表示”是否...“)。

     

在Java中,我看过小类的定义,其唯一目的是返回多个值。这种方法的优点是记录了返回值的类型和含义(至少如果你选择明确的名称并放入注释!)。但在我看来,它相当冗长。

     

当我第一次查看早期Java规范时,我惊讶地发现没有办法返回多个值。我想游说补充一下,所以我试着提出一个既简单又非常引人注目的用例。我无法这样做!所以我没有尝试游说。 Java的设计者非常清楚地试图避免大量的花里胡哨(和语法糖),并且肯定有很多话要说。

答案 6 :(得分:1)

我想在大多数情况下,一个返回值就足够了,函数(或Lambda演算)的数学概念也有一个返回值,所以语言设计者试图坚持使用“标准”是可以理解的。实际上,具有需要多个返回值的若干功能可能令人困惑并且可能是设计不良的标志,例如,缺少复合类。

返回多个值的“经典”方法是使用元组。有些语言有内置的Tuple类型(如Scala),但您可以自己定义所有支持某种形式的类型参数的语言(模板,泛型......)。对于Java,有一个很好的JavaTuple库。

答案 7 :(得分:1)

函数必须填充明确定义的任务。除了你总能返回一个数组之外:如果你需要从不同的数据类型中返回不同的值,那么你的软件设计可能会出现问题。

除此之外,人们更容易阅读具有一个返回值的函数。

答案 8 :(得分:1)

Lua也支持多个返回值:例如,您可以编写以下内容:

function foo()
    return 1, 2, 3
end

a, b, c, d = foo()

执行后,a,b,c将保持值1,2,3,d将为零。您可以采用相同的方式执行以下操作:

function bar()
   return true, 2, 3
end

if bar() then
   -- do something intelligent
end

if语句在这种情况下只能与返回的第一个值一起使用 - 如果你需要其他值,你必须像往常一样将它们存储在变量中:

a, b, c = bar()
if a then
   -- do something intelligent
end

所以你看到:在Lua中,所有不需要的返回值都被丢弃了(比如示例中的2,3和if)。

答案 9 :(得分:0)

该函数返回一个答案,为什么它会被设计为提供更多答案?答案可以是您喜欢的任何数据结构,因此它可以包含许多值:)

答案 10 :(得分:0)

您可以在perl中执行此操作:

sub foo
{
   return (10, 20);
}

my ($a, $b) = foo();  # sets $a to 10 and $b to 20

其他语言的类似结构。

答案 11 :(得分:0)

帮助阅读源代码。 以这种方式对人类友好的SOOOOO! 如果此函数具有多个返回值,则无法写入此行:

 if (SomeFunction(a, b) != SUCCESS)
 {
    // do error handling
 }

答案 12 :(得分:0)

我认为问题在于内存分配和堆栈组织 主要是函数调用时的上下文切换。 功能框架存储在堆栈中 该框架包含函数变量,通用寄存器和返回值 我知道的很多