Почему я получаю UndefVarError в макросе Julia - PullRequest
1 голос
/ 30 сентября 2019

Я изучаю Джулию, и, в частности, я пытаюсь понять макросы, поэтому я нашел среди прочего Некоторые полезные макросы для Джулии - Github , и в процессе их расшифровки яполучил это поведение в REPL:

julia> macro once_then(expr::Expr)
         @assert expr.head == :while
         esc(quote
           $(expr.args[2]) # body of loop
           $expr # loop
         end)
       end
@once_then (macro with 1 method)

julia> i = 0
0

julia> @once_then while i < 10
       i += 1
       end
ERROR: UndefVarError: i not defined
Stacktrace:
 [1] macro expansion at ./REPL[34]:2 [inlined]
 [2] top-level scope at ./REPL[31]:5

julia> i
1

Он явно имел доступ к i в первой итерации цикла, поскольку он увеличивал его, но затем i стал Undef ed где-то междуконец первого цикла и начало второго? Из того, что я вижу, скобки после esc должны включать все до конца цикла ...

Я буквально просто скопировал код в терминал, и я получил то же поведение отМакрос @until найден в Язык Джулии - До цикла , поэтому я не думаю, что проблема может быть связана с самим кодом ... Есть ли что-то важное, что я упускаю?

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

1 Ответ

2 голосов
/ 30 сентября 2019

Ваш макрос в порядке. проблема заключается в объеме задействованных переменных. (для получения дополнительной информации посмотрите на это: JuliaLang - область действия переменных в двух словах, переменная i в i = 0 находится в глобальной области видимости, где цикл находится в локальной области видимости. REPL, вы можете добавить эту комбинацию клавиш global, чтобы ваш код работал:

julia> @once_then while i < 10
       global i += 1
       end

другой вариант - сделать все это в функции, поэтому все переменные имеют локальную область видимости:

function fn()
i = 0
@once_then while i < 10
        i += 1
        end
    return i
end
...