Пытаюсь понять макрос Джулии @isdefined - PullRequest
2 голосов
/ 02 мая 2019

Привет. Я пытаюсь понять, как работает макрос @isdefined.

Я ожидал, что блок 1 распечатает 1 2 3 4, но ничего не печатает.

Также связано, я ожидал, что блок 2 распечатает 2 3 4 5, но выдает ошибку: «a не определен».

# Chunk 1
for i = 1:5
    if @isdefined a
        print(a)
    end
    a = i
end
# Chunk 2
for i = 1:5
    if i > 1
        print(a)
    end
    a = i
end

Может ли кто-нибудь помочь объяснить, что не так в каждом куске?Спасибо.

1 Ответ

3 голосов
/ 02 мая 2019

Причина в том, что a является локальной переменной в области действия цикла for.Теперь важной частью является то, что цикл for следует следующему правилу, определенному здесь :

for циклов, while циклов и пониманий имеют следующее поведение: любойновые переменные, введенные в их области видимости, заново выделяются для каждой итерации цикла

Это означает, что присвоение a в конце цикла не переносит на следующуюитерация, потому что когда начинается новая итерация, старое значение a отбрасывается, как a выделяется заново.Он определяется только после a=i присваивания.

Поэтому у вас есть следующее поведение:

julia> for i = 1:5
           if @isdefined a
               println("before: ", a)
           end
           a = i
           if @isdefined a
               println("after: ", a)
           end
       end
after: 1
after: 2
after: 3
after: 4
after: 5

Однако, если a определено во внешней области, то его значение неfor цикл локальный и сохраняется между итерациями, поэтому у вас есть, например:

julia> let a
           for i = 1:5
               if @isdefined a
                   println("before: ", a)
               end
               a = i
               if @isdefined a
                   println("after: ", a)
               end
           end
       end
after: 1
before: 1
after: 2
before: 2
after: 3
before: 3
after: 4
before: 4
after: 5

и

julia> let a
           for i = 1:5
               if i > 1
                   println(a)
               end
               a = i
           end
       end
1
2
3
4

Я использовал let блок, но это может быть любой видвнешняя область видимости, кроме глобальной области видимости (в этом случае вам придется изменить a = i на global a = i, чтобы получить тот же эффект).

...