Замыкание различий между Ref, Var, Agent, Atom, с примерами

Я очень новичок в Clojure. Можете ли вы, ребята, дать мне объяснения с реальными сценариями мира. Я имею в виду, где использовать Ref, Var, Agent, Atom. Я читал книгу, но все еще не мог понять примеры из реального мира.

5 ответов

Я очень рекомендую "Радость Clojure" или "Программирование Clojure" для реального ответа на этот вопрос, я могу воспроизвести краткий отрывок из мотивов для каждого:

Начните с просмотра этого видео о понятии идентичности и / или изучения здесь.

  • Ссылки предназначены для согласованного синхронного доступа к "множеству идентичностей".
  • Атомы предназначены для несогласованного синхронного доступа к одному идентификатору.
  • Агенты предназначены для несогласованного асинхронного доступа к одному идентификатору.
  • Vars предназначены для локальных изолированных идентификаторов потоков с общим значением по умолчанию.

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

Несогласованный доступ используется, когда требуется обновить только одну личность, это очень распространенный случай.

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

Асинхронный доступ - это "запустить и забыть" и позволить Идентичности достичь своего нового состояния в свое время.

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

Атомы для независимого состояния, которое должно быть синхронизировано между потоками. Если вам никогда не понадобится изменять состояние атома и что-либо еще одновременно, использование at Atom безопасно (в частности, если во всей программе есть только один фрагмент состояния, вы можете поместить его в атом), В качестве нетривиального примера, если вы пытаетесь кэшировать возвращаемые значения функции (то есть запомните его), использование атома, вероятно, безопасно - состояние невидимо для всего, что находится за пределами функции, поэтому вам не нужно беспокоиться об изменении состояния внутри функции что-нибудь испортило.

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

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

Что касается примеров из реальной жизни, то если вы предоставите пример того, что вы пытаетесь сделать, мы можем сказать вам, что использовать.

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

Используйте переменную, когда данные не изменятся. Это происходит всякий раз, когда вы используете def или большинство функций, которые начинаются с def лайк defn,

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

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

Используйте агента, когда вы хотите что-то изменить, но вам все равно, когда. Это может быть длительное вычисление или запись чего-либо в файл или сокет. Обратите внимание, что с последним вы должны использовать send-off,

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

Я написал статью с кратким изложением разницы между ними и помогу выбрать, когда использовать какой.

Доля государства - когда использовать переменные, атомы, агенты и ссылки?

Я надеюсь, что это поможет людям, ищущим ответы в этой теме.

Некоторые ссылки из статьи после предложения @tunaci:

Варс

Вары являются глобальными для всех потоков.

Не меняйте переменные после создания. Это технически возможно, но это плохая идея по многим причинам.

атомы

Разделите доступ к изменяемому состоянию для всех потоков. Изменение происходит синхронно. Повторите попытку, когда другой поток изменит состояние во время выполнения.

Не используйте не идемпотентные функции и функции с длительным временем выполнения

Агенты

Разделите доступ к изменяемому состоянию для всех потоков. Изменение происходит асинхронно.

Refs

Работы аналогичны транзакциям базы данных. Пишите и читайте защищены в dosync. Вы можете работать на многих ссылках, безопасных в сделке.

И блок-схема, когда использовать какой: блок-схема

Пожалуйста, посмотрите на изображение на сайте, потому что некоторые обновления всегда возможны.

Это сложная и длинная тема, чтобы дать полный ответ без копирования и прошлой статьи, поэтому, пожалуйста, прости меня, я перенаправлю тебя на сайт:)

Атомы, рефери и агенты - немного освещения здесь http://blog.jayfields.com/2011/04/clojure-state-management.html

Другие вопросы по тегам