Как @Michael Paul и @crstnbr уже ответили в комментариях, правила области видимости были изменены ( Область переменных в Julia ). Циклы for
и while
вводят новую область видимости и не имеют доступа к внешним (глобальным) переменным. Вы можете получить доступ к области, используя ключевое слово global
, но рекомендуемый рабочий процесс заключает ваш код в функции.
Одним из преимуществ нового дизайна является то, что пользователь вынужден избегать таких глобальных конструкций, которые непосредственно влияют на производительность функций - которые не могут быть устойчивыми по типу при обращении к глобальным переменным.
Один недостаток - путаница при экспериментировании в REPL и обнаружении таких ошибок.
По моему мнению, новое поведение является более чистым с точки зрения предсказуемости. Однако это было очень тяжелое и продолжительное обсуждение во всем сообществе Юлии;)
В настоящее время обсуждается, будет ли REPL изменен на поведение, аналогичное старому, с использованием let
-wraps: https://github.com/JuliaLang/julia/issues/28789
Это то, что не практично делать вручную (гораздо сложнее, чем с помощью ключевого слова global
), см. Пример Stefan Karpinski: https://github.com/JuliaLang/julia/issues/28789#issuecomment-414666648
В любом случае, ради полноты (, хотя я бы не рекомендовал делать это ), здесь есть версия, использующая global
:
myfriends = ["Ted", "Robyn", "Barney", "Lily", "Marshall"]
i = 1;
N = length(myfriends)
while i <= N # you cannot even call a function here
# with a global, like length(myfriends)
global i, myfriends
friend = myfriends[i]
println("Hi $friend, it's great to see you!")
i += 1
end
Обратите внимание, что это также полностью верно:
myfriends = ["Ted", "Robyn", "Barney", "Lily", "Marshall"]
greet(friend) = println("Hi $friend, it's great to see you!")
for friend in myfriends
greet(friend)
end