хорошо, функция broadcast
выполняется в процессе. Поэтому эта функция должна быть доступна для всех процессов. Даже если один и тот же фрагмент исходного кода в том же модуле порождает процесс, который выполняет функцию из того же модуля, эта функция должна быть экспортирована из этого модуля, чтобы сделать ее доступной.
Это подводит меня к разнице между spawn(fun() -> broadcast() end).
и spawn(?MODULE, broadcast, [])
. Последний называется Spawning with <b>MFA</b>
. В этом методе функция должна быть экспортирована из модуля, чтобы ее можно было выполнить. Первый, однако, уникален, его fun
.
Чтобы понять этот метод: spawn(fun() -> broadcast() end).
, нам нужно сравнить его с этим: spawn(fun() -> ?MODULE:broadcast() end).
. Теперь давайте поговорим о позднем из двух
spawn(fun() -> ?MODULE:broadcast() end).
Теперь, если функция
broadcast
НЕ экспортируется в модуль:
?MODULE
, процесс завершится сбоем. Обратите внимание, что в этом случае функция находится в том самом модуле, в котором написан этот фрагмент исходного кода.
spawn(fun() -> broadcast() end).
В этом случае функция должна находиться в том самом модуле, в котором написан этот фрагмент исходного кода. Тем не менее, я думаю, что компилятор преобразует это в приведенный выше, так что порожденный процесс говорит, что функция, которую вы ищете, находится в модуле
?MODULE
.
Я не совсем гуру в компиляторах или системы времени выполнения, но я думаю, что вы будете использовать этот ответ. Мой сильный совет: в большинстве вашего исходного кода используйте это
spawn(fun() -> ?MODULE:broadcast() end).
или
spawn(fun() -> some_module:broadcast() end).
, даже если фрагмент кода или функция находится в том же самом модуле, чем этот:
spawn(fun() -> broadcast() end).
. Из моего личного опыта код становится управляемым и понятным. Я получаю эту приятную иллюзию, что порожденный процесс должен пойти и найти функцию из указанного модуля, а затем выполнить с заданными аргументами.