Почему блоки core.async go возвращают канал?

Я понимаю, что «блоки перехода» (будь то go или go-loop или, возможно, другие конструкции) возвращают канал. Однако я никогда не понимал предназначения этого канала. Я хотел бы знать, как его использовать. Возможно, я создаю дополнительные каналы, когда мне это не нужно.


person Chris Murphy    schedule 26.03.2016    source источник


Ответы (1)


Я использую канал возврата блока go как дескриптор, который я могу передать другой функции (не только макросу), которая хочет синхронизироваться с завершением блока go. В качестве альтернативы я могу выполнить блокировку чтения на канале, чтобы гарантировать завершение выполнения go-блока.

Вот простой пример (не предназначенный для использования в каком-либо производственном коде для вычисления суммы), который выполняет двустороннее распараллеливание:

(defn par-sum [coll]
  (let [half-n (/ (count coll) 2)
        [left right] (split-at half-n coll)
        left-sum-chan (async/go (core/reduce + 0 left))
        right-sum (core/reduce + 0 right)
        left-sum (async/<!! left-sum-chan)]
    (+ left-sum right-sum)))

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

person shams    schedule 31.03.2016
comment
Так как это блок go, нет такого понятия, как возвращаемое значение, которое могло бы быть для функции. Чтобы обойти это, блок go возвращает канал, в который он отправляет возвращаемое значение. - person Chris Murphy; 01.04.2016