#scala #akka
#scala #akka
Вопрос:
Я замечаю во многих примерах akka, чтобы показать, как вы можете использовать изменяемый тип внутри актера, который они используют:
var users: Map[String, String] = ...
Почему люди не используют:
val users = scala.collection.mutable.Map[String, String]()
Вы все еще можете изменить карту, но просто не можете изменить ссылку.
Есть ли существенная разница между двумя подходами?
Комментарии:
1. Потому что local
var
более сдержан, чем amutable.Map
. Например, с первым вы можете просто вернуть значение var и убедиться, что вы не делитесь изменчивостью с внешним миром, со вторым вам нужно будет выполнить защитную копию перед возвратом. Таким образом, даже если amutable.Map
более эффективен для дополнений, если вы постоянно делитесь им, это будет более неэффективно.2. Это особенно верно, если вы видите, что
var
это общедоступно — тогда вы должны предположить, что кто-то еще где-то получает доступ к вашим данным, и если они хотят их обновить, им лучше пройти через ваш шлюз (здесь: сгенерированный сеттер, который вы можете позже заменить чем-то более сложным).3. хорошо, в этом случае речь идет скорее о предоставлении свойств внешнему миру, которые должны быть конфиденциальными…
4. Потому что изменяемая коллекция (не находящаяся в параллельном режиме) не является потокобезопасной. Другие потоки могут одновременно считывать и записывать один и тот же объект. Неизменяемая переменная коллекции потокобезопасна, потому что они могут изменять ссылку вместо объекта, хотя разные потоки могут считывать разные версии переменной (что обычно приемлемо в распределенной системе). В однопоточной среде оба имеют одинаковое поведение
5. @texasbruce Актеры Akka являются однопоточными, поэтому безопасность потоков не является проблемой.
Ответ №1:
В общем случае возникают проблемы с видимостью этих данных, как обсуждалось в комментариях. Но это не применимо в случае субъекта, потому что единственный способ доступа к данным — через сообщения Субъекту. Состояние субъекта не отображается напрямую для кода вне субъекта, поэтому нет проблем с совместным использованием изменяемых данных.
Основное различие между использованием var
и использованием mutable
заключается в том, что при var
замене всей коллекции, но при mutable
обновлении коллекции на месте. Обновление коллекции на месте не является функциональным, поэтому mutable
версия, как правило, поощряет нефункциональный код, тогда var
как версия поощряет более функциональный стиль программирования.
Но состояние актера действительно должно храниться в Behavior
(для типизированных актеров) или управляться через context.become
в классических актерах. В обоих этих случаях состояние состоит из неизменяемых значений, поэтому, опять же, var
модель ближе к этому, чем использование mutable
коллекций.
Комментарии:
1. В контексте Akka следует также отметить, что a
val
ofmutable
открывает возможный способ незаметно разрушить однопоточную иллюзию, которую предоставляет Akka: помещение изменяемой коллекции в сообщение без защитной копии может означать, что код вне субъекта может напрямую манипулировать состоянием внутри субъекта (и это было бы дажеразрывcontext.become
или типизированныйBehavior
).