Примечание. Я помещаю этот Python и С++, потому что я видел примеры в обоих, но вопрос является языковым агностиком.
Метод или метод класса, который модифицирует объект, имеет два варианта: изменить данные непосредственно в рассматриваемом объекте или создать новую копию и вернуть ее, оставив исходный нетронутый. Как правило, вы можете определить, что есть, посмотрев на то, что вернулось из функции.
Иногда вы найдете функцию, которая пытается сделать то же самое, изменить исходный объект, а затем вернуть копию или ссылку на этот объект. Есть ли когда-нибудь случай, когда это дает какое-либо преимущество перед тем, как делать только одно или другое?
Я видел пример Fluent Interface или Цепочка метода, который основан на возврате ссылки на объект, но это похоже на частный случай, который должен быть очевиден в контексте.
Мой первый плохой пример приведен прямо из документации Python и иллюстрирует проблему изменчивых параметров по умолчанию. Для меня этот пример нереалистичен: если функция изменяет свой параметр, то нет смысла иметь по умолчанию, и если он вернет копию, то копия должна быть сделана до того, как будут сделаны какие-либо изменения. Проблема существует только потому, что она пытается сделать оба.
def f(a, L=[]):
L.append(a)
return L
Второй пример - Microsoft С++ в CStringT::MakeUpper
. В документации говорится об возвращаемом значении:
Возвращает копию строки, но все символы верхнего регистра.
Это приводит к тому, что оригинал остается неизменным. Часть проблемы заключается в том, что документация вводит в заблуждение, если вы посмотрите на прототип, вы обнаружите, что он возвращает ссылку на строку. Вы не заметите этого, если не присмотритесь и присвоите результат новой компиляции строк без ошибок. Удивление приходит позже.