Почему методы не могут возвращать несколько значений - PullRequest
5 голосов
/ 23 июня 2011

Просто любопытно, есть ли какое-то техническое ограничение в наличии множественных возвращаемых значений для методов в таких языках, как java, c, c ++ или ограничение только по спецификации?На ассемблере я понимаю, что вызываемый абонент может выдвинуть одно значение для регистрации.

Ответы [ 10 ]

19 голосов
/ 23 июня 2011
  1. Потому что во времена C для хранения возвращаемого значения использовался / был один регистр.
  2. Поскольку, если вам нужно больше значений, вы можете просто вернуть struct, ссылку (в Java / C #) или указатель.
  3. Поскольку вы можете использовать параметр out.

Разрешение нескольких возвращаемых значений увеличит сложность, и это просто обходится. Там нет причин для этого быть там. (Действительно, в C ++ вы можете вернуть tuple (из TR1, C ++ 11 или boost), который фактически является множественными возвращаемыми значениями)

9 голосов
/ 23 июня 2011

Свой дизайн, потому что нет необходимости разрешать несколько значений в операторе возврата.Вы всегда можете определить структуру со всеми необходимыми членами, а также создать экземпляр структуры и вернуть ее.Простой!

Пример,

struct Person
{
   std::string Name;
   int Age;
   std::string Qualification;
   //...
};

Person GetInfo()
{
    Person person;
    //fill person's members ...
    return person;
}

Вы можете использовать std::pair, std::vector, std::map, std::list и так далее.В C ++ 0x вы также можете использовать std::tuple.

6 голосов
/ 23 июня 2011

Если Джинн дал тебе только одно желание, ты мог бы просто захотеть иметь любое количество желаний.То же самое только с одним возвращаемым значением из метода.Вы можете использовать возвращаемое значение в качестве указателя на адрес, где находится объект, полный атрибутов, а затем запросить эти атрибуты (свойства) ... Таким образом, на самом деле ограничений нет.: -)

Веселое кодирование и много счастливых возвращений: -)

3 голосов
/ 23 июня 2011

Это просто решение и потому что люди привыкли к нему.В принципе, не было бы ничего, что мешало бы разработчику языка реализовать синтаксис, подобный этому:

(int, int, int) call(int x, int y, int z);

, и вызов функции мог бы выглядеть так:

(a, b, c) = call(1, 2, 3);

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

Конечно, оператор return:

(int, int, int) call(int x, int y, int z);
{
  return x+1, y+1, z+1
}

Вы можете даже подумать о таких полезных приложениях, как:

(err, filehandle) = OpenFileDialog(...)

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

2 голосов
/ 23 июня 2011

В основном это связано с историческими причинами, связанными с соглашениями о машинном вызове.Кроме того, потому что C не имеет синтаксиса сопоставления с образцом на стороне вызываемого для получения результатов.Обратите внимание, что языки, такие как ML или Haskell, имеют синтаксически легкий тип кортежа, который идеально подходит для возврата нескольких значений.

Отредактировано:

На самом деле немного подумав, я думаю, если вы захотитеразделенные волосы, ML и Haskell по-прежнему имеют «одиночное» возвращаемое значение.Просто синтаксически кортежи настолько легки, что удобно думать о функциях, возвращающих несколько значений, а не об одном кортеже.

Чтобы быть абсолютно строгими, есть два языка, о которых я могу думать, которые имеют "правильное" множественное числоВозвращает -значения, которые не являются просто кортежами в некоторой форме.Одним из них является схема, (cf call-with-values), а другим - MATLAB:

function [x,y] = myFunc(a, b)
   ...
end

[p, q] = myFunc(3,4)

. В обоих этих языках существует специальное синтаксическое различие между одним значением, которое оказывается совокупным (consячейка, массив соответственно) и несколько значений.

2 голосов
/ 23 июня 2011

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

Только мои 2 цента.

1 голос
/ 23 июня 2011

Это просто решение, принятое дизайнерами языка и / или ABI. Не больше, не меньше. На ассемблере вы можете сами принимать эти решения - я не уверен, что означает ваш последний комментарий.

0 голосов
/ 27 июня 2016

Полезно поддержать это, и учитывая то, как люди находят это удобным на других языках, C и Java тоже могут двигаться в этом направлении.

C ++ уже стандартизирует видудобная, интуитивно понятная обработка возвращаемых значений, знакомых, например, по Ruby и python для стороны, вызывающей функцию , что более важно, чем у самого return, поскольку одна функция, вероятно, вызывается из большого числаsites.

В частности, документ C ++ 17 здесь (см. также формулировку здесь ) описывает нотацию ...

auto [x,y,z] = expression;

... где выражение может быть функцией, возвращающей - или любое другое выражение, вычисляющее - массив, tuple или struct со всеми public членами.Приведенному выше может предшествовать const, чтобы сделать локальные переменные const.

Функция также документирует это ...

for (const auto& [key,value] : mymap)
    ...

..., что позволяет избежать повторного использованияменее выразительные ->first и ->second.

Поскольку C ++ движется в этом направлении, вполне вероятно, что C и другие производные от C языки будут внимательно относиться к этому.

0 голосов
/ 23 июня 2011

На самом деле есть как минимум 2 способа вернуть несколько значений.

Сначала необходимо создать структуру или класс, поместить все возвращаемые данные и вернуть их.

секунда - передать параметры по ссылке (неконстантно) и поместить туда значения.

0 голосов
/ 23 июня 2011

Нам не нужна возможность возвращать несколько значений, встроенных в язык C ++, потому что библиотека работает просто отлично:

std::tuple<int,float> func()
{
    return std::make_tuple(1, 2.f);
}

int i;
float f;

std::tie(i, f) = func();

Большинство других языков имеют аналогичную функциональность в своей стандартной библиотеке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...