Clojure различия между Ref, Var, Agent, Atom, с примерами

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

Ответ 1

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

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

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

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

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

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

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

Ответ 2

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

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

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

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

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

Ответ 3

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

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

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

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

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

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

Ответ 4

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

Share state - при использовании vars, атомов, агентов и ссылок?

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

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

Варс

Vars являются глобальными для каждого потока.

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

Атомы

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

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

Агенты

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

Refs

Refs работает подобно транзакциям базы данных. Запись и чтение защищать в досинк. Вы можете работать со многими refs safe в транзакции.

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

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

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