Julia - 流程控制

众所周知,Julia 中程序的每一行都会依次求值,因此它提供了许多控制语句(其他编程语言所熟悉的)来控制和修改求值流程。

以下是 Julia 编程语言中控制流程的不同方法 −

  • 三元和复合表达式

  • 布尔 switching 表达式

  • If elseif else end(条件求值)

  • For end(迭代评估)

  • While end(迭代条件评估)

  • Try catch error throw(异常处理)

  • Do 块

三元表达式

它的形式为expr ? a:b。 它被称为三元,因为它需要三个参数。 expr 是一个条件,如果为 true,则将计算 a,否则 b。 下面给出了示例 −

julia> A = 100
100

julia> A < 20 ? "Right" : "wrong"
"wrong"

julia> A > 20 ? "Right" : "wrong"
"Right"

布尔 Switching 切换表达式

顾名思义,布尔切换表达式允许我们在满足条件(即条件为真)时计算表达式。 有两个运算符用于组合条件和表达式 −

&& 运算符(与)

如果在布尔切换表达式中使用此运算符,则当第一个条件为 true 时,将计算第二个表达式。 如果第一个条件为 false,则不会计算表达式,仅返回条件。

示例

julia> isodd(3) && @warn("An odd Number!")
┌ Warning: An odd Number!
└ @ Main REPL[5]:1

julia> isodd(4) && @warn("An odd Number!")
false

|| 运算符(或)

如果在布尔切换表达式中使用此运算符,则仅当第一个条件为 false 时才会计算第二个表达式。 如果第一个条件为真,则无需计算第二个表达式。

示例

julia> isodd(3) || @warn("An odd Number!")
true

julia> isodd(4) || @warn("An odd Number!")
┌ Warning: An odd Number!
└ @ Main REPL[8]:1

If、elseif 和 else

我们还可以使用 if、elseif、else 来执行条件。 唯一的条件是所有条件构造都应以 end 结束。

示例

julia> fruit = "Apple"
"Apple"

julia> if fruit == "Apple"
         println("I like Apple")
      elseif fruit == "Banana"
         println("I like Banana.")
         println("But I prefer Apple.")
      else
         println("I don't know what I like")
      end

I like Apple

julia> fruit = "Banana"
"Banana"

julia> if fruit == "Apple"
         println("I like Apple")
      elseif fruit == "Banana"
         println("I like Banana.")
         println("But I prefer Apple.")
      else
         println("I don't know what I like")
      end
      
I like Banana.
But I prefer Apple.

for 循环

一些常见的迭代示例是 −

  • 通过列表进行工作

  • 一组值或

  • 从起始值到结束值。

我们可以通过使用"for"循环(for…end 构造)来迭代各种类型的对象,例如数组、集合、字典和字符串。 让我们通过以下示例来理解语法 −

julia> for i in 0:5:50
                  println(i)
            end
0
5
10
15
20
25
30
35
40
45
50

在上面的代码中,变量"i"获取数组中每个元素的值,因此将以 5 为步长从 0 到 50。

示例(迭代数组)

如果我们迭代数组,每次循环都会检查它是否发生变化。 使用"push!"使数组在特定循环的中间增长时应小心。

julia> c = [1]
julia> 1-element Array{Int64,1}:
1

julia> for i in c
         push!(c, i)
         @show c
         sleep(1)
      end
      
c = [1,1]
c = [1,1,1]
c = [1,1,1,1]
...

注意 − 要退出输出,请按 Ctrl+c。

循环变量

循环变量是遍历每一项的变量。 它只存在于循环内部。 循环结束后它就会消失。

示例

julia> for i in 0:5:50

                  println(i)
            end
0
5
10
15
20
25
30
35
40
45
50

julia> i
ERROR: UndefVarError: i not defined

示例

Julia 提供了 global 关键字来记住循环外循环变量的值。

julia> for i in 1:10
                  global hello
                  if i % 3 == 0
                     hello = i
                  end
               end
               
julia> hello
9

循环内声明的变量

与循环变量类似,循环内声明的变量在循环结束后将不存在。

示例

julia> for x in 1:10
                  y = x^2
                  println("$(x) squared is $(y)")
               end

输出

1 squared is 1
2 squared is 4
3 squared is 9
4 squared is 16
5 squared is 25
6 squared is 36
7 squared is 49
8 squared is 64
9 squared is 81
10 squared is 100

julia> y
ERROR: UndefVarError: y not defined

Continue 语句

Continue 语句用于跳过循环内的其余代码,并使用下一个值再次开始循环。 它主要用于在特定迭代中您想要跳到下一个值的情况。

示例

julia> for x in 1:10
            if x % 4 == 0
               continue
            end
            println(x)
            end

输出

1
2
3
5
6
7
9
10

推导式

生成和收集类似于 [n for n in 1:5] 的项目称为数组推导式。 有时也称为列表推导式。

示例

julia> [X^2 for X in 1:5]
5-element Array{Int64,1}:
 1
 4
 9
 16
 25

我们还可以指定我们想要生成的元素类型 −

示例

julia> Complex[X^2 for X in 1:5]
5-element Array{Complex,1}:
 1 + 0im
 4 + 0im
 9 + 0im
 16 + 0im
 25 + 0im

枚举数组

有时我们希望逐个元素地遍历数组,同时跟踪该数组中每个元素的索引号。 Julia 有 enumerate() 函数来完成此任务。 这个函数为我们提供了某个东西的可迭代版本。 该函数将生成索引号以及每个索引号处的值。

示例

julia> arr = rand(0:9, 4, 4)
4×4 Array{Int64,2}:
 7 6 5 8
 8 6 9 4
 6 3 0 7
 2 3 2 4
 
julia> [x for x in enumerate(arr)]
4×4 Array{Tuple{Int64,Int64},2}:
 (1, 7) (5, 6) (9, 5) (13, 8)
 (2, 8) (6, 6) (10, 9) (14, 4)
 (3, 6) (7, 3) (11, 0) (15, 7)
 (4, 2) (8, 3) (12, 2) (16, 4)

压缩数组

使用 zip() 函数,您可以同时处理两个或多个数组,方法是先获取每个数组的 1st 元素,然后获取 2nd 元素,依此类推。

以下示例演示了zip()函数的用法 −

示例

julia> for x in zip(0:10, 100:110, 200:210)
                  println(x)
      end
(0, 100, 200)
(1, 101, 201)
(2, 102, 202)
(3, 103, 203)
(4, 104, 204)
(5, 105, 205)
(6, 106, 206)
(7, 107, 207)
(8, 108, 208)
(9, 109, 209)
(10, 110, 210)

Julia 还处理不同大小数组的问题,如下所示 −

julia> for x in zip(0:15, 100:110, 200:210)
               println(x)
            end
(0, 100, 200)
(1, 101, 201)
(2, 102, 202)
(3, 103, 203)
(4, 104, 204)
(5, 105, 205)
(6, 106, 206)
(7, 107, 207)
(8, 108, 208)
(9, 109, 209)
(10, 110, 210)

julia> for x in zip(0:10, 100:115, 200:210)
               println(x)
            end
(0, 100, 200)
(1, 101, 201)
(2, 102, 202)
(3, 103, 203)
(4, 104, 204)
(5, 105, 205)
(6, 106, 206)
(7, 107, 207)
(8, 108, 208)
(9, 109, 209)
(10, 110, 210)

嵌套循环

仅使用逗号 (;) 即可将循环嵌套在另一个循环中。 您无需重复 forend 关键字。

示例

julia> for n in 1:5, m in 1:5
                  @show (n, m)
               end
(n, m) = (1, 1)
(n, m) = (1, 2)
(n, m) = (1, 3)
(n, m) = (1, 4)
(n, m) = (1, 5)
(n, m) = (2, 1)
(n, m) = (2, 2)
(n, m) = (2, 3)
(n, m) = (2, 4)
(n, m) = (2, 5)
(n, m) = (3, 1)
(n, m) = (3, 2)
(n, m) = (3, 3)
(n, m) = (3, 4)
(n, m) = (3, 5)
(n, m) = (4, 1)
(n, m) = (4, 2)
(n, m) = (4, 3)
(n, m) = (4, 4)
(n, m) = (4, 5)
(n, m) = (5, 1)
(n, m) = (5, 2)
(n, m) = (5, 3)
(n, m) = (5, 4)
(n, m) = (5, 5)

While 循环

当条件为真时,我们使用 while 循环来重复某些表达式。 结构类似于while…end

示例

julia> n = 0
0

julia> while n < 10
                     println(n)
                     global n += 1
                  end
 0
 1
 2
 3
 4
 5
 6
 7
 8
 9

异常

异常或 try...catch 构造用于编写检查错误并优雅处理错误的代码。 流行语处理代码中出现的问题。 它允许程序继续而不是逐渐停止。

示例

julia> str = "string";
julia> try
               str[1] = "p"
            catch e
               println("the code caught an error: $e")
               println("but we can easily continue with execution...")
            end
the code caught an error: MethodError(setindex!, ("string", "p", 1), 0x0000000000006cba)
but we can easily continue with execution...

Do 块

Do 块是另一种类似于列表推导式的语法形式。 它从最后开始,并朝着开始的方向努力。

示例

julia> Prime_numbers = [1,2,3,5,7,11,13,17,19,23];

julia> findall(x -> isequal(19, x), Prime_numbers)
1-element Array{Int64,1}:
 9

从上面的代码我们可以看到find()函数的第一个参数。 它在第二个上运行。 但是使用 do 块,我们可以将函数放入 do…end 块结构中。

julia> findall(Prime_numbers) do x
                  isequal(x, 19)
               end
1-element Array{Int64,1}:
 9