#julia
Вопрос:
Я использую Julia 1.6.2 и Juno, и у меня есть этот код:
println("0.5772156649015328606065120900824024310421")
jmax = 1000000
gamma = 0
j = 1
for j = jmax:-1:1
gamma = gamma 1.e0/j
end
gamma = gamma - log(jmax)
println("$gamma, reverse order sum $(jmax)")
Ошибки нет, когда я запускаю каждую строку по порядку с помощью Ctrl Enter.
Но у меня есть ошибка, и я получаю следующее сообщение, когда я делаю «выполнить все» (Ctrl Shift Enter).
Предупреждение: Присвоение «гамма» в мягкой области неоднозначно, поскольку существует глобальная переменная с тем же именем: «гамма» будет рассматриваться как новая локальная. Устраните неоднозначность, используя «локальную гамму» для подавления этого предупреждения или «глобальную гамму» для присвоения существующей глобальной переменной.
ОШИБКА: Ошибка загрузки: ошибка UndefVarError: гамма не определена
Я не знаю, почему происходит такая разница. Можете ли вы объяснить это?
Комментарии:
1. docs.julialang.org/en/v1/manual/variables-and-scoping/. … Похоже, что Юнона, когда вы делаете «запустить все», запускает скрипт в неинтерактивном режиме. В общем, я рекомендую вам переключиться на VS Code, так как в настоящее время это рекомендуемая среда разработки для Julia.
2. VS-код имеет такое же поведение. Идея заключается в том, что запуск файла построчно (или блок за блоком) работает так же, как и REPL, но запуск файла в целом эквивалентен
include
его запуску.3. Да, я не хотел подразумевать, что VS — код будет вести себя по-другому, просто Юнона не получает такого внимания к обслуживанию, как VS-код.
Ответ №1:
Проблема здесь в том, что у Джулии есть два разных способа организации «области видимости», видимости переменных, в зависимости от того, выполняется ли она в интерактивном режиме, например, в REPL или построчно в редакторах, или нет.
Полное объяснение находится по ссылке, которую вы предоставили, но вопрос здесь в том, что вы сначала определяете глобальную переменную gamma
, а затем редактируете эту переменную внутри цикла for, который вводит (как и функции) их собственную область действия.
В построчном режиме переменная gamma
, на которую вы ссылаетесь в цикле for, считается глобальной переменной, которую вы уже определили, и все в порядке.
Однако в режиме выполнения «всего сценария» требуется, чтобы вы явно указали «Я имею в виду глобальную переменную gamma
«, так как это соединение не выполняется автоматически.
Итак, в вашем случае просто измените строку внутри цикла for в:
global gamma = gamma 1.e0/j
чтобы явно указать, что вы хотите работать с глобальным gamma
, а не с возможным (несуществующим) локальным. Это позволит ему работать как в построчном, так и в файловом режиме.
Комментарии:
1. Я знаю, что здесь нет простого решения, и понимаю, какая сложная история потребовалась, чтобы попасть сюда… но это все равно похоже на уродливую бородавку, которой я бы хотел, чтобы у Джулии не было.
Ответ №2:
Расширяя ответ выше:
Вы должны обернуть свой код в функцию.
Внутри функции гамма является локальной переменной, а не глобальной, поэтому она используется в цикле for (обратите внимание, что это верно только в том случае, если переменная определена в функции до цикла, переменные, определенные только внутри цикла, не видны снаружи).
Кроме того, в функции Джулия может выводить типы, поэтому вычисление выполняется намного быстрее (может быть в 100 раз).
fuction do_stuff()
jmax = 1000000
gamma = 0.0 # define it as a float for type stability!
j = 1
for j = jmax:-1:1
gamma = gamma 1.e0/j
end
gamma = gamma - log(jmax)
println("$gamma, reverse order sum $(jmax)")
end
do_stuff()
Правила определения области видимости переменных поначалу кажутся неинтуитивными, но для них есть веские причины, и они подробно описаны в руководстве Julia.