Зачем использовать var, когда вы можете использовать val с изменяемым типом?

#scala #akka

#scala #akka

Вопрос:

Я замечаю во многих примерах akka, чтобы показать, как вы можете использовать изменяемый тип внутри актера, который они используют:

 var users: Map[String, String] = ...
  

Почему люди не используют:

 val users = scala.collection.mutable.Map[String, String]()
  

Вы все еще можете изменить карту, но просто не можете изменить ссылку.

Есть ли существенная разница между двумя подходами?

Комментарии:

1. Потому что local var более сдержан, чем a mutable.Map . Например, с первым вы можете просто вернуть значение var и убедиться, что вы не делитесь изменчивостью с внешним миром, со вторым вам нужно будет выполнить защитную копию перед возвратом. Таким образом, даже если a mutable.Map более эффективен для дополнений, если вы постоянно делитесь им, это будет более неэффективно.

2. Это особенно верно, если вы видите, что var это общедоступно — тогда вы должны предположить, что кто-то еще где-то получает доступ к вашим данным, и если они хотят их обновить, им лучше пройти через ваш шлюз (здесь: сгенерированный сеттер, который вы можете позже заменить чем-то более сложным).

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

4. Потому что изменяемая коллекция (не находящаяся в параллельном режиме) не является потокобезопасной. Другие потоки могут одновременно считывать и записывать один и тот же объект. Неизменяемая переменная коллекции потокобезопасна, потому что они могут изменять ссылку вместо объекта, хотя разные потоки могут считывать разные версии переменной (что обычно приемлемо в распределенной системе). В однопоточной среде оба имеют одинаковое поведение

5. @texasbruce Актеры Akka являются однопоточными, поэтому безопасность потоков не является проблемой.

Ответ №1:

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

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

Но состояние актера действительно должно храниться в Behavior (для типизированных актеров) или управляться через context.become в классических актерах. В обоих этих случаях состояние состоит из неизменяемых значений, поэтому, опять же, var модель ближе к этому, чем использование mutable коллекций.

Комментарии:

1. В контексте Akka следует также отметить, что a val of mutable открывает возможный способ незаметно разрушить однопоточную иллюзию, которую предоставляет Akka: помещение изменяемой коллекции в сообщение без защитной копии может означать, что код вне субъекта может напрямую манипулировать состоянием внутри субъекта (и это было бы дажеразрыв context.become или типизированный Behavior ).