Использование переменной внутри цикла для каждого строки приводит к ошибке - PullRequest
3 голосов
/ 19 сентября 2019

Я пытаюсь понять, почему использование переменной i внутри цикла вызывает проблему

Файл main2.jl ​​:

struct MyStruct
    a::Int32
    b::Int32
    c::String
end

df = DataFrame( A=Int[], B=Int[] )
push!(df, [1, 10])
push!(df, [2, 20])
push!(df, [3, 30])

insertcols!(df, 3, :C => MyStruct.(Int32(0), Int32(0), ""))
insertcols!(df, 3, :D => Vector{MyStruct})

println(df)

i = 1
for r in eachrow(df)
    i = i + 1
end

Я получаю:

julia> include("main2.jl")
|     A |     B |                 D |                    C |
| Int64 | Int64 |          DataType |             MyStruct |
|-------|-------|-------------------|----------------------|
|     1 |    10 | Array{MyStruct,1} | MyStruct(0, 0, \"\") |
|     2 |    20 | Array{MyStruct,1} | MyStruct(0, 0, \"\") |
|     3 |    30 | Array{MyStruct,1} | MyStruct(0, 0, \"\") |
ERROR: LoadError: UndefVarError: i not defined
Stacktrace:
 [1] top-level scope at /usr/home/.../main2.jl:19
 [2] include at ./boot.jl:328 [inlined]
 [3] include_relative(::Module, ::String) at ./loading.jl:1094
 [4] include(::Module, ::String) at ./Base.jl:31
 [5] include(::String) at ./client.jl:431
 [6] top-level scope at REPL[3]:1
in expression starting at /usr/home/.../main2.jl:18

julia> 

1 Ответ

4 голосов
/ 19 сентября 2019

Проблема в том, что i живет в глобальной области видимости, и когда вы пишете цикл for в глобальной области видимости, он создает свою собственную под-область видимости.Вы можете решить эту проблему, изменив цикл for на

i = 1
for r in eachrow(df)
    global i
    i = i + 1
end

Однако, внутри тел функций не нужно этого делать (если i живет в теле функции).

Это сводится к тому, что в Юлии вам часто не нужно писать нетривиальный код в глобальной области видимости.Это считается правильной формой для помещения кода в функции.Если код не находится внутри функции, он не будет скомпилирован, и вы не получите никаких преимуществ в производительности при использовании Julia.Более подробную информацию о правилах определения области можно найти здесь: https://docs.julialang.org/en/v1/manual/variables-and-scoping/

Было много дискуссий по этому вопросу, и то, что люди предпочли бы, вместо этого.Дискуссия более или менее началась здесь: https://github.com/JuliaLang/julia/issues/28789, а затем здесь было предложено решение: https://discourse.julialang.org/t/another-possible-solution-to-the-global-scope-debacle/, а затем теперь обсуждалось новое потенциальное решение: https://discourse.julialang.org/t/new-scope-solution/16707.

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

...