Когда должен параметр использоваться вместо того, чтобы возвратить составной тип?

Он устанавливает их в автоматически создаваемый подкаталог базы кода с именем .eggs как .egg s. Это потому, что .egg разработаны для импорта из любого места.

Таким образом, это, скорее всего, не будет работать в современной среде, потому что пакеты не распространяются как .egg с (что потеряло конкуренцию с .whl с), поэтому setuptools придется собирать их из источника (с bdist_egg ). Что, скорее всего, не удастся для многих широко используемых бинарных пакетов с нетривиальными требованиями к сборке (не говоря уже о необходимом времени и о том, что пакеты также не тестируются как .egg, и могут потерпеть неудачу при такой упаковке). [1119 ]


Вместо этого перечисление требований к сборке в requirements.txt и вызов pip install -r requirements.txt до сборки, похоже, стали широко распространенной практикой. Это не делает setup.py автоматически собираемым из источника pip.

Я пытался установить их самостоятельно из setup.py, но это оказалось хрупким (например, если у пользователя нет прав на запись в site-packages).

Лучшее решение, принятое, по крайней мере, рядом крупных проектов, - это просто заставить setup.py потерпеть неудачу, если их нет. Это особенно полезно, если требования не к Python, а к библиотекам C, поскольку setup.py все равно не знает, как установить их в конкретной среде. Как видите, это естественным образом дополняет requirements.txt.

6
задан Jay Bazuzi 19 April 2009 в 21:13
поделиться

11 ответов

Out также может использоваться для операций, которые могут завершиться ошибкой (обычно это можно найти в методах, запускающих Try *).

Например, TryParse будет возвращать логическое значение, указывающее успех / неудачу, при использовании значения out в качестве результата. Это избавляет от необходимости генерировать исключения.

4
ответ дан 8 December 2019 в 17:27
поделиться

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

С другой стороны, если у вас есть несколько выходных параметров и возвращаемое значение, которые логически связаны друг с другом (например, имя, фамилия, номер телефона), то, вероятно, имеет смысл создать соответствующий тип. (например, «Контакт») и верните его.

Одной из альтернатив для опции TryGetValue является использование типов значений, допускающих значение NULL, если рассматриваемое значение является типом значения. Например, int.TryParse мог иметь подпись:

int? TryParse(string text)

(с перегрузкой, конечно, IFormatProvider ).

3
ответ дан 8 December 2019 в 17:27
поделиться

Вы точно указали причину, по которой его следует использовать. Чтобы уменьшить сложность кода.

if (TryGetValue(myObj))
{
    [...]
}

более аккуратен, чем

Result tryGetValueResult = TryGetValue();
if (tryGetValueResult.Found)
{
    [...]
}

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

3
ответ дан 8 December 2019 в 17:27
поделиться

Они полезны в (редкой) ситуации, когда вам нужно вернуть значение из конструктора. Например, конструктор Mutex имеет логический параметр out, который указывает, был ли создан новый Mutex или существующий мьютекс с именем уже существует.

3
ответ дан 8 December 2019 в 17:27
поделиться

Если объект может быть нулевым. Тогда не нужно заострять внимание.

0
ответ дан 8 December 2019 в 17:27
поделиться

Выходные параметры обычно находятся на хрупкой стороне. Выходя за пределы примера и рассматривая проблему в целом: книга Билла Вагнера «Более эффективный C #» описывает довольно умный подход к этому, он также подробно описан здесь здесь .

Следующий код будет работать в этом случае.

public class Tuple<T1,T2>
{
  public T1 First {get;private set;}
  public T2 Second {get; private set;}
  Tuple(T1 first, T2 second)
  {
    First = first;
    Second = second;
  }
}


using ComplexPair = Tuple<bool,object>;

public class SomeOtherClass 
{
  public ComplexPair GetComplexType ()
  {
    ...
    return new ComplexPair(true, new object);

  }
}
1
ответ дан 8 December 2019 в 17:27
поделиться

The out keyword enforces a couple of things via the compiler..
The caller doesn't have to initialize the param. The callee can't read from the param but has to write to it before exiting the method.

out more importantly makes the intent visible as the caller has to specify the out keyword when making a method call

You can use out when you need to return multiple values from a method (without stuffing and destuffing them from an object[]). (The section that loves to return bSuccess from every function would love the out keyword.)
В примере, который вы разместили. Основное возвращаемое значение TryParse - это успешное выполнение операции разбора. Таким образом, это возвращаемое значение, но наиболее вероятной последующей потребностью будет получение проанализированного объекта, если он завершится успешно. Таким образом, вместо того, чтобы заставить всех вызывающих абонентов выполнять этот шаг, TryParse избавляет вас от хлопот, давая его как выходной параметр ... так как он уже сделал это как часть проверки CanParse.

2
ответ дан 8 December 2019 в 17:27
поделиться

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

0
ответ дан 8 December 2019 в 17:27
поделиться

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

0
ответ дан 8 December 2019 в 17:27
поделиться

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

ReturnType<T>

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

0
ответ дан 8 December 2019 в 17:27
поделиться

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

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

Затем для получения значений из функции требуются параметры out .

-3
ответ дан 8 December 2019 в 17:27
поделиться