Function 与数据相关的函数:多入一出:为什么?

Function 与数据相关的函数:多入一出:为什么?,function,arguments,return-value,Function,Arguments,Return Value,我有一个我自己无法回答的问题,但这似乎是一个需要澄清的基本问题: 为什么有些语言将函数返回的数据限制为单个项 这有什么好处吗?还是从数学中带过来的练习 例如(在Scala中): 如果我想返回多个项目,我不能像刚才对输入参数那样说(现在输入虚构的Scala land) 甚至在返回命名数据时: def login(username: String, password: String): (user: User, context: Context, serverMessage: String) 因为

我有一个我自己无法回答的问题,但这似乎是一个需要澄清的基本问题:

为什么有些语言将函数返回的数据限制为单个项

这有什么好处吗?还是从数学中带过来的练习

例如(在Scala中):

如果我想返回多个项目,我不能像刚才对输入参数那样说(现在输入虚构的Scala land)

甚至在返回命名数据时:

def login(username: String, password: String): (user: User, context: Context, serverMessage: String)

因为通常返回的数据被分配给一个变量。只有少数几种语言可以在一句话中指定两个变量

A = sum(1,2)
B,C = dateTime()
从技术上讲,它们返回多个参数是没有问题的,因为参数是堆叠的,问题在于分配。这里需要一个示例:

/* div example */
#include <stdio.h>
#include <stdlib.h>

int main ()
{
  div_t divresult;
  divresult = div (38,5);
  printf ("38 div 5 => %d, remainder %d.\n", divresult.quot, divresult.rem);
  return 0;
}

没有关系:正如所观察到的,可以返回任意数量的值,即使它们必须“打包”为单个值

假设一种语言只能接受一个元组,并且只能从函数返回一个元组(元组可以是任意大小)。这些函数类似于将向量从一个空间变换到另一个空间的数学函数

然而,原因可能是:

  • 大多数函数只返回一个值,可能是一组值(对象、序列等)。许多语言都支持单个值的分解,即使“只返回一个值”

  • 调用约定和签名更简单:没有特殊情况/开销来表示正在返回n个值:不需要使用堆栈的一部分来返回多个值,一个寄存器就可以了
  • 适应目标体系结构的需要:早期的语言,尤其是低级语言,受到计算机体系结构的严重影响。例如,在Scala的情况下,它必须在JVM上工作
  • 这就是语言的设计方式。许多(大多数?)语言大量借用现有语言的语法和/或方法。有时这是好的,有时不是那么好。C++满足java满足的C++满足的C,例如:它是关于市场份额的。
  • 它只是工作

  • 即使“只返回一个值”,编程语言也已经有了不同的处理方法。正如本文所述,有些语言允许分解(在赋值过程中,元组返回为“分解”为它的两个值):

    此外,其他语言,如C#,缺少分解,允许通过引用传递(或通过对象的变异模拟):

    当然,还有…;-)

    可能还有更多我不知道的方法


    快乐编码。

    你能举个例子吗?而且,数学也没有规则来反对这一点。集合表示法返回任意数量的项。问得好。我将试着回答。这个问题归结为:为什么一些编程语言没有处理元组的语法糖?@Blender:set符号“返回”单个对象,即set。集合论的整个思想是用一个对象来代替它们的集合。@larsmans:我不确定我在评论(facepalm)时的想法。在Scheme中,函数可以返回,但没有多重赋值结构,只有多重绑定形式。我相信在Common Lisp中情况类似。@larsman,谢谢你的回答,我喜欢这句话“然而,程序中的值通常代表概念整体;在许多情况下,计算产生的多个结果缺乏这种一致性。”“调用约定和签名更简单”我认为这是最初的原因。“语言大量借用现有语言”,这就是为什么它仍然如此普遍的原因。其余的原因只是额外津贴:)
    A = sum(1,2)
    B,C = dateTime()
    
    /* div example */
    #include <stdio.h>
    #include <stdlib.h>
    
    int main ()
    {
      div_t divresult;
      divresult = div (38,5);
      printf ("38 div 5 => %d, remainder %d.\n", divresult.quot, divresult.rem);
      return 0;
    }
    
    long quot, rem;
    quot, rem = div(38,5)
    
    def multiMath (i):
      return (i + i, i * i)
    
    double, squared = multiMath(4)
    # doubled is 8
    # squared is 16
    
    void multiMath (int a, out int doubled, out int squared) {
      doubled = a + a;
      squared = a * a;
    }
    
    int d, s;
    multiMath(4, out d, out s);
    // d is now 8
    // s is now 16
    
    class ANewClassForThisFunctionsReturn {
      ...
    }