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这种方式在 Julia 里经常作为
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;