Давать понять, что функция может изменять свои параметры - PullRequest
2 голосов
/ 17 июля 2009

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

SomeObject A(15), B
B = DoSomething(A)
print(A + " " + B + "\n)

Читая этот код, вы ожидаете, что результат будет что-то вроде «15 75», т.е. A - это то, для чего вы его построили. Однако большинство языков позволяют DoSomething изменять значение A. В C ++ вы можете определить, возможно это или нет, посмотрев объявление DoSomething, например, посмотрев, определяется ли параметр как неконстантная ссылка. Тем не менее, во многих языках, таких как Python, на самом деле невозможно сказать, не прочитав код для функции, чтобы убедиться, что она никогда не изменится.

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

Почему языки обычно не требуют какого-либо явного синтаксиса при вызове, чтобы сказать «да, этот объект можно изменить», например, сказать «B = DoSomething (inout A)»?

Существуют ли какие-либо стандарты кодирования, которые помогают предотвратить возникновение проблем, кроме «никогда не изменяйте параметр, передаваемый в функцию»?

Ответы [ 4 ]

1 голос
/ 17 июля 2009

Мой предпочтительный шаблон проектирования для этого - неизменяемые классы данных.

С изменяемыми классами вам нужно подумать, будут ли они изменены.

Пояснение, насколько я понимаю, Python передается по значению, как Java и C (без модификаторов). Но то, что вы передаете, обычно является изменчивым объектом.

(Редактировать: почти все основные языки теперь следуют этой семантике. Наиболее заметным исключением является Лисп, где вы можете не только изменять изменяемые объекты, но и переназначать значение, на которое указывает переменная.)

1 голос
/ 17 июля 2009

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

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

1 голос
/ 17 июля 2009

«Стандарты кодирования» различаются в зависимости от языка и среди пользователей / команд. C ++ имеет const -корректность, которая при правильном использовании считается стандартом кодирования. C # имеет out и ref параметры для очевидных случаев. Я бы сказал, что единственная реальная согласованность в широком диапазоне языков - это то, что изменения параметров всегда должны документироваться в постусловиях функции.

0 голосов
/ 17 июля 2009

Это напрямую не делает ваш фрагмент кода более понятным, но я все равно хочу упомянуть об этом: мы используем соглашение об именах для параметров, чтобы отображать именно то, что вы хотите. Мы используем префиксы «in», «out» и «io». Таким образом, объявление DoSomething будет выглядеть как DoSomething (ioSomeObject inA). При работе в Visual Studio с Visual Assist вы получите всплывающее окно с типами и именами параметров, и это документирует возможные побочные эффекты. На мой взгляд, это более понятно, чем документирование постусловий.

С уважением,

Sebastiaan

...