#f# #immutability
#f# #неизменяемость
Вопрос:
Проблема в том, должен ли метод экземпляра в любом случае изменять объект, содержащий метод, или он должен возвращать новый экземпляр? Я новичок в F # и концепции полной изменяемости, которая предлагается для F #.
Пока просто использую псевдокод, если мне не нужно быть более конкретным.
Первая мысль — просто добавить сообщение в список сообщений на объекте:
class Something
ctr(messages)
_messages.Add(messages)
AddMessage(message)
_messages.Add(message)
Второе — создать новый список, который объединяет старый список и новое сообщение. Затем я бы создал новый экземпляр и отправил обратно.
class Something
ctr(messages)
_messages.Add(messages)
AddMessage(message)
newMessageList = _messages.Join(message)
return new Something(newMessageList)
Я слишком много думаю о неизменности?
Ответ №1:
На мой взгляд, ответ зависит от ваших требований. Неизменяемый стиль, вероятно, более идиоматичен и был бы разумным значением по умолчанию. Однако одна приятная особенность F # заключается в том, что вы можете выбирать, что делать, исходя из ваших потребностей; в коде, использующем мутацию, нет ничего изначально неправильного. Вот некоторые вещи, которые следует учитывать:
- Иногда изменяемый подход приводит к повышению производительности, особенно при использовании в однопоточном контексте (но обязательно измеряйте реалистичные сценарии, чтобы быть уверенным!)
- Иногда неизменяемый подход лучше использовать в многопоточных сценариях
- Иногда требуется взаимодействовать с библиотеками, которые проще использовать с императивным кодом (например, API, использующий a
System.Action<_>
). - Вы работаете в команде? Если да, то являются ли они опытными разработчиками C #? Опытные разработчики F #? Какой код им будет легче всего читать (возможно, изменяемый стиль)? Какой код вам будет проще всего поддерживать (возможно, неизменяемый стиль)?
- Вы просто делаете это как упражнение? Тогда может быть полезно практиковать неизменяемый стиль.
Отступая еще дальше, есть несколько других моментов, которые следует учитывать:
- Вам действительно нужен метод экземпляра? Часто использование функции с привязкой к разрешению в модуле более идиоматично.
- Вам действительно нужен новый номинальный тип для того, что вы делаете? Если это просто тонкая оболочка вокруг списка, вы можете рассмотреть возможность использования
list
s напрямую.
Ответ №2:
Поскольку вы выполняете программирование на основе классов, что является одним из способов (довольно неудачных) объектно-ориентированного программирования, вы будете выполнять изменение состояния на месте, а не возвращать новое состояние (поскольку это то, что можно было бы ожидать, когда вы выполняете OO).
Если вы действительно хотите перейти к неизменности, я бы посоветовал вам использовать больше концепций FP, таких как модули, функции (а не методы, которые у вас есть в программировании на основе классов), рекурсивные типы данных и т.д.
Мой ответ слишком общий, и подходящий ответ заключается в том, как этот ваш класс будет вписываться в общую картину дизайна вашего приложения.