Функции, относящиеся к данным: много входов, один выход: почему? - PullRequest
2 голосов
/ 13 ноября 2011

У меня есть вопрос, на который я не могу ответить сам, но это кажется принципиально хорошим вопросом для прояснения:

Почему некоторые языки ограничивают данные, возвращаемые функцией, одним элементом?

Это служит какой-то пользе? Или это практика по математике?

Пример (в Scala):

def login(username: String, password: String): User

Если я хочу вернуть несколько элементов, я не могу сказать это таким же образом, как я только что сделал для входных аргументов (теперь вводя воображаемую страну Скала)

def login(username: String, password: String): (User, Context, String)

Или даже с возвращенными именованными данными:

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

Ответы [ 2 ]

1 голос
/ 13 ноября 2011

Нет никакого отношения: как было отмечено, может быть возвращено произвольное количество значений, даже если они должны быть "упакованы" в одно значение.

Представьте себе язык, который может только принимать один кортеж и может возвращать только один кортеж из функции (кортежи могут быть любого размера). Эти функции тогда напоминают математическую функцию, преобразующую вектор из одного пространства в другое.

Однако, несколько причин, почему это может быть так:

  1. Большинство функций возвращают только одно значение, которое может быть набором значений (объект, последовательность и т. Д.). Разложение одного значения поддерживается на нескольких языках, даже если «возвращается только одно значение».
  2. Соглашения о вызовах и сигнатуры более просты: нет особого случая / издержек, чтобы сигнализировать, что возвращаются n-значения: нет необходимости использовать часть стека для возврата нескольких значений, подойдет один регистр.
  3. Необходимость вписываться в целевую архитектуру: ранее, особенно языки нижнего уровня, находились под сильным влиянием компьютерной архитектуры. Например, в случае с Scala он должен работать на JVM.
  4. Это просто, как язык был разработан. Многие (большинство?) Языков в значительной степени заимствуют - синтаксис и / или методологии - из существующих языков. Иногда это хорошо, иногда не так хорошо. Умиротворение C # Удовлетворение Java C ++ Удовлетворение C, например: все дело в доле рынка.
  5. Это просто работает.

Даже при «возврате только одного значения» языки программирования уже по-разному справляются с ним. Как отмечено в посте, некоторые языки допускают декомпозицию (кортеж, возвращаемый как «декомпозированный» на два значения во время присваивания):

def multiMath (i):
  return (i + i, i * i)

double, squared = multiMath(4)
# doubled is 8
# squared is 16

Кроме того, другие языки, такие как C #, в которых отсутствует декомпозиция, допускают передачу по ссылке (или эмулируют ее с помощью мутации объекта):

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 {
  ...
}

Вероятно, есть еще несколько методов, о которых я не знаю.

Удачного кодирования.

0 голосов
/ 13 ноября 2011

Поскольку обычно возвращаемые данные присваиваются переменной.И только несколько языков, которые могут назначать две переменные в одном предложении.

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;
}

VS

long quot, rem;
quot, rem = div(38,5)
...