2016-03-06 2 views
1

Я с трудом понимая смысл этого примера:Futures в Clojure

(let [result (future (println "this prints once") 
       (+ 1 1))] 
    (println "deref: " (deref result)) 
    (println "@: " @result)) 

The author explains:

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

Я не понимаю; строка будет печататься один раз даже без разыменования будущего. Что должен преподавать этот пример?

+3

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

ответ

5

Я согласен, что это тонкий. Дело в том, что future является разовой оценкой. Несомненно, побочный эффект println возникает, если вы используете «результат» или нет. Фактически, побочный эффект происходит без дальнейшего устранения «результата», как вы заметили. Простое «результат» связывания приводит к возникновению побочного эффекта println.

Что еще более важно, идея состоит в том, что в результате «результат» дважды явно не заставляет его оценивать (или привязывать) дважды. Другими словами, это не вызывает побочный эффект println. Вы получаете кешированное значение 2, оба раза вы deref.

Можно было бы ожидать, что его разделение дважды приведет к тому, что он будет связан дважды, и поэтому дважды выполните команду println. Но это не так. Вместо этого вы получаете кешированное, измененное значение только один раз. Дело здесь в том, что побочный эффект возникает при связывании, а не при дешифровании, и что разделение дважды не требует второго связывания.

2

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

Я думаю, автор хотел показать, что тело future не будет переустанавливаться, если вы разыщите его более одного раза.