Julia 学习笔记——3. 流程控制
简单过一遍 Julia 中的流程控制。
条件语句
if 条件语句和其它语言一样,注意其中的条件表达式不需要括号
1
2
3
4
5
6
7
8
9
10
11
12x = 3;
y = 2;
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
# x is greater than y
C/C++ 使用
else if;Python 使用elif;MATLAB 使用elseif,Julia 也使用elseif。
需要注意的是,Julia 要求 if 和 elseif
所接受的条件必须是 Bool
值,不接受隐式转换,例如下面的语句是错误的 1
2
3if 1 # error
println("1 is true")
end
还需要说明的是:和 Python 一样,Julia 在 if 语句中不会开辟独立的局部作用域。
Julia 支持三元运算符,可以用来简化判断语句,例如 1
2
3
4x = 3;
y = 2;
m = x > y ? x : y # 3
Julia 还提供了一个内置函数 ifelse() 1
2ifelse(1>0, 1, 0) # 1
ifelse(1<0, 1, 0) # 0
循环语句
while 循环语句也和其它语言一样 1
2
3
4
5
6
7
8
9
10
11
12i = 0
while i <= 10
println(i)
i += 2
end
# 0
# 2
# 4
# 6
# 8
# 10
for 循环语句也和 MATLAB/Python
很类似,需要注意范围是闭区间而不是左闭右开,Julia
提供了三种等效的方式(=,in,∈),使用上没有区别
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25for i = 1:5
println(i)
end
# 1
# 2
# 3
# 4
# 5
for s in ["foo", "bar", "baz"]
println(s)
end
# foo
# bar
# baz
for s ∈ ["foo", "bar", "baz"]
println(s)
end
# foo
# bar
# baz
在循环中对于 break 和 continue
的支持也是类似的,无需重复。
有意思的是,Julia 支持将多重 for 循环写在一起,遍历笛卡尔积,例如
1
2
3
4
5
6
7
8
9
10
11
12
13for i = 1:3, j = 2:4
println((i, j))
end
# (1, 2)
# (1, 3)
# (1, 4)
# (2, 2)
# (2, 3)
# (2, 4)
# (3, 2)
# (3, 3)
# (3, 4)
在这种情况下,使用 break 语句会直接跳出整个循环。
需要注意,这里不能误写作
for i = 1:3; j = 2:4,因为会被视作复合表达式。
while 循环和 for 循环通常会引入变量局部作用域,这里暂时不作讨论。
复合表达式
有时我们只是希望将几个表达式按顺序组合到一起,依次运算,并使用最后一个表达式的值作为整体的结果,Julia
提供了 begin ... end 语法来完成这个功能,例如
1
2
3
4
5
6x = begin
a = 1
b = 2
a + b
end
# x = 3
也可以写在一行中,此时表达式之间必须使用 ; 分隔
1
x = begin a = 1; b = 2; a + b end
可以使用 () 代替
begin ... end,此时表达式之间总是不能省略 ;
1
2
3
4
5x = (a = 1;
b = 2;
a + b)
x = (a = 1; b = 2; a + b)
异常控制
抛出和捕获异常的语法和 Python,C++ 都差不多。
捕获异常 1
2
3
4
5
6
7
8try
x = sqrt(-1)
println("result: $x")
catch e
println("exception:\n$e")
finally
println("finally")
end
输出形如 1
2
3exception:
DomainError(-1.0, "sqrt was called with a negative real argument but will only return a complex result if called with a complex argument. Try sqrt(Complex(x)).")
finally
主动抛出异常 1
2
3f(x) = x>=0 ? exp(-x) : throw(DomainError("x<0"))
f(-1)
输出形如 1
2
3
4
5
6
7ERROR: DomainError with x<0:
Stacktrace:
[1] f(x::Int64)
@ Main ./REPL[7]:1
[2] top-level scope
@ REPL[9]:1
补充
日志打印
Julia 内置了一些信息输出的工具,包括
@debug、@info,@warn 和
@error,例如 1
2
3
4
5
6
7
8
9
10
11
12julia> @debug("hi")
julia> @info("hi")
[ Info: hi
julia> @warn("hi")
┌ Warning: hi
└ @ Main REPL[12]:1
julia> @error("hi")
┌ Error: hi
└ @ Main REPL[13]:1
注意这里 @debug 的信息默认不会显示出来。
更完整的日志系统可以使用
Logging这个包。
