Использование глобальной декларации внутри оператора if (код Юлии) - PullRequest
0 голосов
/ 28 апреля 2019

Почему я объявляю переменные глобальными, если они находятся в одном и том же блоке elseif?Чего мне не хватает?


function f(N)

for n in 0:N
    if n == 0
        fibonacci_n = 0
        fibonacci_n_1 = fibonacci_n
    elseif n == 1
        fibonacci_n = 1
        fibonacci_n_1 = fibonacci_n
        fibonacci_n_2 = fibonacci_n_1
    else
        global fibonacci_n_1, fibonacci_n_2
        fibonacci_n = fibonacci_n_1 + fibonacci_n_2
        fibonacci_n_1 = fibonacci_n
        fibonacci_n_2 = fibonacci_n_1
    end        
    @printf "%5i %10i\n" n fibonacci_n
end

end

1 Ответ

2 голосов
/ 28 апреля 2019

Проблема, с которой вы столкнулись, не связана с глобальной областью действия, и вам не нужно объявлять здесь что-либо глобальное. global ключевое слово необходимо, если вы хотите получить доступ к глобальной переменной для записи.

Ваше ключевое слово global вводит новые глобальные привязки fibonacci_n_1 и fibonacci_n_2. Неважно, где вы поместите ключевое слово global в область действия. Вы даже можете получить доступ к последним значениям fibonacci_n_1 и fibonacci_n_2 после завершения функции: попробуйте f(5); println(fibonacci_n_1) в глобальной области видимости.

Если вы удалите объявление global в своей функции, fibonacci_n_1 и fibonacci_n_2 будут определены в локальной области действия for -loop. Следовательно, не будет проблемы доступа к глобальной области. Однако проблема, с которой вы столкнетесь, будет связана со следующим поведением переменных, представленных в блоках цикла.

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

https://docs.julialang.org/en/v1/manual/variables-and-scoping/#For-Loops-and-Comprehensions-1

Это означает, что вы не можете получить доступ к значению или привязке переменной в предыдущей итерации , если вы введете эту переменную внутри for -петля. Это не аналогично поведению переменных, введенных в циклах Python или MATLAB.

Вместо этого вы можете определять такие переменные вне цикла for, но внутри функции.

function f(N)

fibonacci_n, fibonacci_n_1, fibonacci_n_2 = 0, 0, 0
for n in 0:N
    if n == 0
        fibonacci_n = 0
        fibonacci_n_1 = fibonacci_n
    elseif n == 1
        fibonacci_n = 1
        fibonacci_n_2 = fibonacci_n_1
        fibonacci_n_1 = fibonacci_n
    else
        fibonacci_n = fibonacci_n_1 + fibonacci_n_2
        fibonacci_n_2 = fibonacci_n_1
        fibonacci_n_1 = fibonacci_n
    end        
    @printf "%5i %10i\n" n fibonacci_n
end

end

Более подробное обсуждение области переменных в Julia см. В разделе Scope of Variable документации Julia.

...