美文网首页
JULIA-控制流

JULIA-控制流

作者: 9016 | 来源:发表于2018-11-01 10:49 被阅读25次

    复合表达式

    有时,使用一组表达式按顺序计算几个子表达式,将最后一个子表达式的值作为其值返回。这一组表达式叫做复合表达式。
    复合表达式的表现形式有两种:begin块和 (;) 链。
    begin块的形式:

    julia> c = begin
    a = 10
    b = a^2
    log10(b)
    end
    2.0
    

    (;) 链的形式:

    julia> z=(a = 10; b = a^2; log10(b))
    2.0
    

    begin块也可以写在一行:

    julia> begin a = 10; b = a^2; log10(b) end
    2.0
    

    条件表达式

    julia> function looking4large(x,y)
    if x > y
    println("前面的大")
    elseif y >x
    println("后面面的大")
    else
    println("一样大")
    end
    end
    looking4large (generic function with 1 method)
    
    julia> looking4large(1,1)
    一样大
    
    julia> looking4large(100,1)
    前面的大
    
    julia> looking4large(100,10000)
    后面的大
    

    也可以在一行里写出条件表达式,只用“?”做判断,“:”作为条件块的间隔:

    julia> looking4large(x,y) = println(x > y ? "前面的大" :
                                        y > x ? "后面的大" : "一样大")
    looking4large (generic function with 1 method)
    
    julia> looking4large(1,1)
    一样大
    
    julia> looking4large(2,1)
    前面的大
    
    julia> looking4large(2,10)
    后面的大
    

    短路求值

    && 和 || 布尔运算符,连接两个布尔表达式,仅以最短路径计算最少的表达式来确定整个链的布尔值,因此被称为短路求值。
    在表达式中a && b,b仅在a求值时才计算子表达式true。
    在表达式中a || b,b仅在a求值时才计算子表达式false。
    😎说人话就是,&&:从而,||:要不就
    类似的&和|,却不是以最短路径求值,它们会把表达式两侧都计算出结果,再做“且”、“或”计算。
    以下以实例演示四种运算符的不同:

    julia>  t() = (println('t');true)
    t (generic function with 1 method)
    
    julia> f() = (println('f');false)
    f (generic function with 1 method)
    
    julia> t()&&f()
    t
    f
    false
    
    julia> f()&&t()
    f
    false
    
    julia> t()||f()
    t
    true
    
    julia> f()||t()
    f
    t
    true
    
    julia> t()&f()
    t
    f
    false
    
    julia> f()&t()
    f
    t
    false
    
    julia> t()|f()
    t
    f
    true
    
    julia> f()|t()
    f
    t
    true
    

    循环

    等了好久终于写到了循环,记得我国软件业某先辈说过,所谓编程就是if/else加上循环,应该没有记错,他是中英文混着说的。
    Julia的循环提供两种结构形式:while和for,记得二十多年前用某语言写代码时因为没有for循环,用do wihle手工模写一个for,因为代码功底差,绕了一下午没绕出来的悲惨景象。Julia很大方,一次提供了两个,爱用哪个用哪个。
    先看while循环:

    julia> i = 1
    1
    
    julia> while i <= 5
    println(i)
    global i += 1
    end
    1
    2
    3
    4
    5
    

    再看for循环:

    julia> for i = 1: 5
    println(i)
    end
    1
    2
    3
    4
    5
    

    for还有各种花式写法:
    1、数组形式

    julia> for i in [1,3,5]
    println(i)
    end
    1
    3
    5
    

    2、竟然能遍历字符串

    julia> for i ∈ ["one","two","three"]#你要用“in”也可以,Julia1.0中继续支持
    println(i)
    end
    one
    two
    three
    

    和所有提供了for的高级语言一样,for是可以嵌套的,当然你用朴素的while也可以做循环嵌套,前面说了,哥曾经掉过这个坑,不想再进去了:

    julia> for i = 11:13,j = 21:23
    println(i, " | ", j)
    end
    11 | 21
    11 | 22
    11 | 23
    12 | 21
    12 | 22
    12 | 23
    13 | 21
    13 | 22
    13 | 23
    

    和所有提供了循环结构体的高级语言一样,Julia也提供了break,循环中遇到break,无论break所在代码块埋得多深,无条件跳出最外层的循环体。

    julia> while i <= 5
    if i >3
    break
    end
    println(i)
    global i +=1
    end
    1
    2
    3
    

    有了break就有continue,循环中遇到continue,跳到最近一层的end,不会跳出所有循环体,比较下面两个循环体,体会continue跳出的位置:

    julia>  for i = 1:10, j = 21:23
        if mod(i, 2) == 0
        continue
        end
        println(i, " | ", j)
        end
    1 | 21
    1 | 22
    1 | 23
    3 | 21
    3 | 22
    3 | 23
    5 | 21
    5 | 22
    5 | 23
    7 | 21
    7 | 22
    7 | 23
    9 | 21
    9 | 22
    9 | 23
    
    julia>  for i = 1:10, j = 21:24
        if mod(j, 2) == 0
        continue
        end
        println(i, " | ", j)
        end
    1 | 21
    1 | 23
    2 | 21
    2 | 23
    3 | 21
    3 | 23
    4 | 21
    4 | 23
    5 | 21
    5 | 23
    6 | 21
    6 | 23
    7 | 21
    7 | 23
    8 | 21
    8 | 23
    9 | 21
    9 | 23
    10 | 21
    10 | 23
    

    😎程序每一次经过循环体,都按照循环体的规则被赋值,比较下面两段代码,体会其中不同:

    julia> for i = 1:10
    println(i)
    i = 99
    end
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    julia> for i = 1:10
    i = 99
    println(i)
    end
    99
    99
    99
    99
    99
    99
    99
    99
    99
    99
    

    异常处理

    当程序遇到异常,抛出异常信息,终止程序执行:

    julia> for i = -1:1
    println(sqrt(i))
    end
    ERROR: DomainError with -1.0:
    sqrt will only return a complex result if called with a complex argument. Try sq
    rt(Complex(x)).
    Stacktrace:
     [1] throw_complex_domainerror(::Symbol, ::Float64) at .\math.jl:31
     [2] sqrt at .\math.jl:492 [inlined]
     [3] sqrt at .\math.jl:518 [inlined]
     [4] top-level scope at .\none:2
    

    throw()函数

    throw()函数可以在主动识别异常后,抛出异常信息。例如,某个函数fsqr(x)只对非负数(x>=0?)做了对应的计算安排,如果入参x为负数,可以使用throw()函数抛出 DomaineError 异常:

    julia> fsqr(x) =  x>=0 ? sqrt(x) : throw(DomainError(x,"大于零行吗"))
    f (generic function with 1 method)
    
    julia> fsqr(1)
    1.0
    
    julia> fsqr(-1)
    ERROR: DomainError with -1:
    大于零行吗吗
    Stacktrace:
     [1] f(::Int64) at .\none:1
     [2] top-level scope at none:0
    

    error() 函数

    error 函数用来产生 ErrorException ,并且立即停止程序的正常执行。
    例如我们可以改写上面的fsqr(x)函数,入参x为负数时,抛出错误信息,并立即停止程序运行:

    julia> fsqr(x) =  x>=0 ? sqrt(x) : error(x," 大于于零行吗")
    f (generic function with 1 method)
    
    julia> fsqr(1)
    1.0
    
    julia> fsqr(-1)
    ERROR: -1 大于零行吗
    Stacktrace:
     [1] error(::Int64, ::String) at .\error.jl:42
     [2] f(::Int64) at .\none:1
     [3] top-level scope at none:0
    

    try/catch语句

    try/catch语句可以对try后面的表达式进行监测,如果异常则进入catch分支,以下还是一平方根为例,本次引入了复数概念:

    julia> fsqr(x) = try
    sqrt(x)
    catch
    sqrt(complex(x, 0))
    end
    fsqr (generic function with 1 method)
    
    julia> fsqr(0)
    0.0
    
    julia> fsqr(1)
    1.0
    
    julia> fsqr(-1)
    0.0 + 1.0im
    

    😎当捕获异常后,执行sqrt(complex(x, 0))。

    finally语句

    异常会导致程序提前退出,例如前面提到的error() 函数。关键字 finally 可以解决这个问题,下面的例子中,无论catch语句后面的代码块是否被执行,finally 语句后面的代码块都会被执行。

    f = open("file")
    try
        # operate on file f
    catch
        #抛出异常信息
    finally
        close(f)
    end

    相关文章

      网友评论

          本文标题:JULIA-控制流

          本文链接:https://www.haomeiwen.com/subject/fpvotqtx.html