Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
386 views
in Technique[技术] by (71.8m points)

scope - While without global

This snippet of code is from 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

giving this error when run with Julia v1.0

UndefVarError: i not defined

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

But when i += 1 is replaced with global i += 1 it works. I guess this was still working in v0.6 and the tutorial will be adapted once the new Intro to Julia is published this Friday.

I was just wondering, is it possible, to make a while loop without stating a global variable?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

As @Michael Paul and @crstnbr already replied in the comments, the scoping rules have been changed (Scope of variables in Julia). The for and while loop introduce a new scope and have no access to the outside (global) variables. You can get scope access using the global keyword but the recommended workflow is wrapping your code in functions.

One of the benefits of the new design is that the user is forced to avoid such global constructs which directly affect the performance of functions - which cannot be type stable when they access global variables.

One downside is the confusion when experimenting in the REPL and seeing such errors.

In my opinion the new behaviour is the cleaner one with respect to predictability. It was however a very tough and long-running discussion within the whole Julia community ;)

There is currently a discussion if the REPL will be changed to behave like the old one by making use of let-wraps: https://github.com/JuliaLang/julia/issues/28789 This is something which is not practical to be done manually (much more complicated then using the global keyword), see the example by Stefan Karpinski: https://github.com/JuliaLang/julia/issues/28789#issuecomment-414666648

Anyways, for the sake of completeness (although I would not recommend doing this) here is a version using 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

Note however that this is also completely valid:

myfriends = ["Ted", "Robyn", "Barney", "Lily", "Marshall"]

greet(friend) = println("Hi $friend, it's great to see you!")

for friend in myfriends
    greet(friend)
end

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...