Julia: Control Flow and Scope of Variables

1,010 阅读2分钟

Julia的控制流与变量作用域

Compound Expressions

Julia中可以使用beginend语句块来进行一系列的运算。

x = 0
z = begin
    x = 1
    y = 2
    x + y  # 最后一行作为语句块的返回值
end
# 这时 x = 1, z = 3

也可以简写为:

z = (x = 1; y = 2; x + y)

begin x = 1; y = 2; x + y end
# 3

同样的,begin-end语句块,我们可以将其独立作为一个计算block,一般地,在REPL环境下执行begin-end语句块会改变它的外部外部作用域的变量值(如果在语句块里执行了赋值语句)。为了不改变外部变量的作用域,可以使用local关键字!

x = 0
z = (local x = 1; local y = 2; x + y)
# 此时 x = 0, z = 3

Conditional Evaluation

Julia条件语句的形式是if, elseif, else, end

function test(x, y)
    if x < y
        println("x is less than y")
    elseif x > y
        println("x is greater than y")
    else
        println("x is equal to y")
    end
end

ifelseif后面接的表达式必须要是一个布尔类型的值,if 1是不允许的。可以使用&&||!来计算各表达式的“与”、“或”、“非”。

1 && true
# ERROR: TypeError: non-boolean (Int64) used in boolean context

if语句甚至是可以有返回值的:

x = 3
if x > 0
    "positive!"
else
    "negative..."
end
# "positive!"

在Julia中,if语句块并没有新建变量的作用域。 或者说,if的使用,不需要去考虑变量的作用域之类的事情。

Julia还支持三元运算符:

println(x < y ? "less than" : "not less than")

Repeated Evaluation: Loops

Julia的循环语句使用关键词forwhile,循环的形式像MATLAB。

i = 0
while i <= 10
    i += 1
end
println(i)  # 11

注意for循环会引入新的作用域:

for j = 1 : 5
    x = "hello"
end
println(j)   # ERROR: UndefVarError: j not defined
println(x)   # # ERROR: UndefVarError: x not defined

循环变量如果在循环前没有定义,在循环结束之后就会消失在外部作用域中!如果在循环前定义了,那么循环不会改变它在外部作用域上的值。

s, i = 0, 0
for i = 1:10
    s += i  # 在REPL中,s指向外部作用域中已经存在的那个s
end
s, i  # (55, 0)

如果要在for循环中修改外部变量的值,建议加上global修饰一下。

Julia可以方便的实现嵌套循环:

for i = 1:2, j = 3:4
    println((i, j))
    if j == 4
        break  # 跳出整个循环
    end
end
# (1,3)
# (1,4)

等价于Python中的:

for i in range(3, 6):
    for j in range(3, i + 1):
        print((i, j))

同样的,Julia内使用breakcontinue关键词来控制循环过程。

for i = 1:10
    if i % 3 != 0
        continue
    end
    println(i)
end

综上,在Julia的循环结构中,需要我们考虑作用域这样一件事情。建议在循环体内,要修改外部变量 或者新建想在循环外使用的变量的时候,加上global关键字修饰;如果只是使用只出现于循环体内的变量,用local关键字修饰变量。

Constants

Julia使用const关键字修饰常量。(就像Java里的final

const x = 1.0
x = 2.0  # warning 但不 Error
x = 2  # Error

常量不允许改变类型,但是可以在不改变类型的情况下进行值的修改(但是会报WARNING!强烈不建议这么做)

Exception Handling

Julia使用throw关键词抛出错误代码:

f(x) = x>=0 ? exp(-x) : throw(DomainError(x, "argument must be nonnegative"))

对于错误处理,Julia使用try-catch-finally,这里的关键词含义和用法与Java、Python等语言类似。

try
    sqrt("ten")
catch e
    println("You should have entered a numeric value", e)
finally
    println("End")
end
# You should have entered a numeric valueMethodError(sqrt, ("ten",), 0x0000000000006cab)
# End