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;