Julia 提供一系列控制流:
begin
和 (;)
if-elseif-else
和 ?: (ternary operator)
&&, ||
和 chained comparisons
while
和 for
try-catch
, error
和 throw
yieldto
前五个控制流机制是高级编程语言的标准。但任务不是:它提供了非本地的控制流,便于在临时暂停的计算中进行切换。在 Julia 中,异常处理和协同多任务都是使用的这个机制。
用一个表达式按照顺序对一系列子表达式求值,并返回最后一个子表达式的值,有两种方法:begin
块和 (;)
链。 begin
块的例子:
julia> z = begin |
x = 1 |
y = 2 |
x + y |
end |
3 |
一个 if
-elseif-else
条件表达式的例子:
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 < y
为真,相应的语句块将会被执行;否则就执行条件表达式 x > y
,如果结果为真,相应的语句块将被执行;如果两个表达式都是假,else
语句块将被执行。
&&
和 ||
布尔运算符被称为短路求值,它们连接一系列布尔表达式,仅计算最少的表达式来确定整个链的布尔值。这意味着: 在表达式 a && b
中,只有 a
为 true
时才计算子表达式 b
在表达式 a || b
中,只有 a
为 false
时才计算子表达式 b
&&
和 ||
都与右侧结合,但 &&
比 ||
优先级高:
julia> t(x) = (println(x); true) |
t (generic function with 1 method) |
julia> f(x) = (println(x); false) |
f (generic function with 1 method) |
julia> t(1) && t(2) |
1 |
2 |
true |
julia> t(1) && f(2) |
1 |
2 |
false |
julia> f(1) && t(2) |
1 |
false |
julia> f(1) && f(2) |
1 |
false |
julia> t(1) || t(2) |
1 |
true |
julia> t(1) || f(2) |
1 |
true |
julia> f(1) || t(2) |
1 |
2 |
true |
julia> f(1) || f(2) |
1 |
2 |
false |
if
语句的一个简洁的替代。 可以把 if <cond> <statement> end
写成 <cond> && <statement> (读作 <cond> *从而* <statement>)
。 类似地, 可以把 if ! <cond> <statement> end
写成 <cond> || <statement>
(读作 要不就 )。
有两种循环表达式: while
循环和 for
循环。下面是 while
的例子:
julia> i = 1; |
julia> while i <= 5 |
println(i) |
i += 1 |
end |
1 |
2 |
3 |
4 |
5 |
当遇到意外条件时,函数可能无法给调用者返回一个合理值。这时,要么终止程序,打印诊断错误信息;要么程序员编写异常处理。
Exception
如果程序遇到意外条件,异常将会被抛出。表中列出内置异常。
Exception |
---|
ArgumentError |
BoundsError |
DivideError |
DomainError |
EOFError |
ErrorException |
InexactError |
InterruptException |
KeyError |
LoadError |
MemoryError |
MethodError |
OverflowError |
ParseError |
SystemError |
TypeError |
UndefRefError |
UndefVarError |
任务是一种允许计算灵活地挂起和恢复的控制流,有时也被称为对称协程、轻量级线程、协同多任务等。
如果一个计算(比如运行一个函数)被设计为 Task
,有可能因为切换到其它 Task
而被中断。原先的 Task
在以后恢复时,会从原先中断的地方继续工作。切换任务不需要任何空间,同时可以有任意数量的任务切换,而不需要考虑堆栈问题。任务切换与函数调用不同,可以按照任何顺序来进行。
任务比较适合生产者-消费者模式,一个过程用来生产值,另一个用来消费值。消费者不能简单的调用生产者来得到值,因为两者的执行时间不一定协同。在任务中,两者则可以正常运行。
Julia 提供了 produce
和 consume
函数来解决这个问题。生产者调用 produce
函数来生产值:
julia> function producer() |
produce("start") |
for n=1:4 |
produce(2n) |
end |
produce("stop") |
end; |