简单过一遍 Julia 中的流程控制。

条件语句

if 条件语句和其它语言一样,注意其中的条件表达式不需要括号

1
2
3
4
5
6
7
8
9
10
11
12
x = 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 严格要求 ifelseif 所接受的条件必须是 Bool 值,不接受隐式转换,例如下面的语句会报错

1
2
3
if 1    # error
println("1 is true")
end

if 语句整体在运行时会将对应分支的执行结果作为返回值,这相比于其他语言有点奇怪。

1
2
3
4
5
6
julia> if x > 0
"positive!"
else
"negative..."
end
"positive!"

需要说明的是:和 Python 一样,Julia 在 if 语句中不会开辟独立的局部作用域。

Julia 支持三元运算符,可以用来简化判断语句,例如

1
2
3
4
x = 3;
y = 2;

m = x > y ? x : y # 3

注意始终只有一个分支会被执行。

Julia 还提供了一个内置函数 ifelse()

1
2
ifelse(1>0, 1, 0) # 1
ifelse(1<0, 1, 0) # 0

循环语句

while 循环语句也和其它语言一样

1
2
3
4
5
6
7
8
9
10
11
12
i = 0
while i <= 10
println(i)
i += 2
end

# 0
# 2
# 4
# 6
# 8
# 10

for 循环语句也和 MATLAB/Python 很类似,需要注意范围是闭区间而不是左闭右开,Julia 提供了三种等效的方式(=in,unicode 字符 ),使用上没有区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
for 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

在循环中对于 breakcontinue 的支持也是类似的,无需重复。

有意思的是,Julia 支持将多重 for 循环写在一起,遍历笛卡尔积,例如

1
2
3
4
5
6
7
8
9
10
11
12
13
for 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
6
x = 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
5
x = (a = 1;
b = 2;
a + b)

x = (a = 1; b = 2; a + b)

异常控制

抛出和捕获异常的语法和 Python,C++ 都差不多。

捕获异常

1
2
3
4
5
6
try
x = sqrt(-1)
println("result: $x")
catch e
println("exception:\n$e")
end

输出形如

1
2
exception:
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)).")

除了最基础的 try catch,Julia 的异常捕获结构还支持 else 语句(无异常时执行)和 finally 语句(总是会执行)。

主动抛出异常

1
2
3
f(x) = x>=0 ? exp(-x) : throw(DomainError("x<0"))

f(-1)

输出形如

1
2
3
4
5
6
7
ERROR: DomainError with x<0:

Stacktrace:
[1] f(x::Int64)
@ Main ./REPL[7]:1
[2] top-level scope
@ REPL[9]:1