Пока без глобальных - PullRequest
       23

Пока без глобальных

0 голосов
/ 27 августа 2018

Этот фрагмент кода взят из JuliaBoxTutorials

myfriends = ["Ted", "Robyn", "Barney", "Lily", "Marshall"]
i = 1;

while i <= length(myfriends)
    friend = myfriends[i]
    println("Hi $friend, it's great to see you!")
    i += 1
end

выдает эту ошибку при запуске с Julia v1.0

UndefVarError: i not defined

Stacktrace:
 [1] top-level scope at ./In[12]:5 [inlined]
 [2] top-level scope at ./none:0

Но когда i += 1 заменяется на global i += 1, это работает. Я думаю, что это все еще работало в v0.6, и учебник будет адаптирован, как только новое вступление к Джулии будет опубликовано в эту пятницу.

Мне было просто интересно, возможно ли сделать цикл while без указания глобальной переменной?

Ответы [ 2 ]

0 голосов
/ 28 августа 2018

Я обнаружил, что это работает в Julia v1.0:

let 
    myfriends = ["Ted", "Robyn", "Barney", "Lily", "Marshall"]
    i = 1;

    while i <= length(myfriends) # this function here seems to work no problem
        friend = myfriends[i]
        println("Hi $friend, it's great to see you!")
        i = i + 1 # gives syntax error when prefixed with global 
    end
end

Фактически, это даст мне синтаксическую ошибку, если я попытаюсь сделать меня глобальным :) в цикле while.

0 голосов
/ 27 августа 2018

Как @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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...