定义函数

函数是的功能是传入一些参数(参数列表arglist ),然后在函数体中进行一些操作,接着返回零个,一个或多个值。多个参数之间用英文逗号分隔(事实上,他们形成了一个元组Tuple,跟返回值一样的结构。可以参考第5章 集合类型 )。这些参数也可是任选类型的,或者用户定义的类型。一般的语法如下:

function fname(arglist)
    # function body...
    return value(s)
end

一个函数的参数列表也可以为空,则写为fname()

下面是一个简单的例子:

function mult(x, y)
       println("x is $x and y is $y")
       return x * y
end

mult 的函数名按照惯例小写且不带下划线的。它们可以包含Unicode字符,这在数学符号中就颇有用。在最后一行return 关键字是可选的;上面例子我们也可以写成x * y。一般情况下,函数会返回最后一个表达式的值。但是写return 的好处主要在于多行代码的函数中,增加可读性。

该函数若被调用,其中n = mult(3, 4) 将返回12,并新的值赋给变量 n。你也可以通过调用fname(arglist) 来执行函数,从而只需要它的副作用(比如改变程序的部分状态;例如,改变全局变量)。return 关键字也可以在函数体某个部分(比如一个判断条件内)从而提前退出函数体,如在本实例:

function mult(x, y)
    println("x is $x and y is $y")
    if x == 1 
      return y 
    end
    x * y
end

在这种情况下,也可以使用不带值的return,使得该函数返回nothing

函数不限于返回单个值。这里是多个返回值的示例:

function multi(n, m)
    n*m, div(n,m), n%m
end

当我们调用multi(8, 2) 时此函数返回 (16,4,0) 这样的多元组。返回值可以被提取出来并赋值给其他变量如x, y, z = multi(8, 2),那么x变成16,y换成4,z变为0。事实上,也可以说Julia总是返回一个值,但该值可以是包含多个成员变量的元组Tuple,并且该元组可以把这些成员变量的值抽出来。

我们还可以使用叫做varargs的函数,从而用一个变量代表多个参数值(多参变量)。其代码如后:

function varargs(n, m, args...)
    println("arguments : $n $m $args")
end

这里 ,n和m是仅有的固定位置参数(可以有更多的或根本没有这样的参数)。args… 用一个元组代表剩余的所有参数。如果我们如此调用varargs(1, 2, 3, 4), 则n为1,m是2,且args有值 (3,4)。当有更多的参数,所述元组可以更大;或者,如果没有参数,元组也可以是空的()

相同的拼接符号splat 也可用于把一个元组或数组中的元素拼接到函数的多参数变量中。例如,我们可以定义第二多参变量的函数:

function varargs2(args...)
    println("arguments2: $args")
end

x = (3, 4),我们可以调用varargs2(1, 2, x...) 从而args 变成元组(1, 2, 3, 4);元组中的x被拼接了。这也适用于数组。如果 x = [10,11,12],然后的args 变成(1, 2, 10, 11, 12)。被调用的函数并不需要一定是一个多参变量的函数。不是的情况下,只需要保证拼接后的参数的数量跟该函数的参数个数完全相同即可。

要认识到Julia 中所有的函数的参数(除了普通的数据,例如数字和字符的)都是按引用传递的。亦即,它们的值在传递过程中是不复制的,这意味着它们可以从函数内部被改变,而变化在调用处又可见。例如,请参考代码:

function insert_elem(arr)
  push!(arr, -10)
end
arr = [2, 3, 4]
insert_elem(arr)
#arr is now [ 2, 3, 4, -10 ]

如本例所示, arr本身已经由函数修改了。

由于Julia 的编译方式,一个函数被使用时必须是已经定义过了的(在其它函数定义中却可使用还未定义的函数)。

显示声明参数类型以限制调用时传递参数的类型,也是有用的举措。对浮点数函数头​​便可如后定义:mult(x::Float64, y::Float64)。当我们如此mult(5, 6) 调用该函数就将得到一个错误。ERROR: *mult* has no method matching mult(::Int64, ::Int64)。如此不难看出Julia 确实是一门强类型语言。浮点参数的函数不接受的整型参数。

如果我们定义函数时不声明参数类型,它是通用的;Julia 的JIT编译器随时待命按需生成适应不同参数类型的函数版本(又称作methods)。如前定义的mult函数,在REPL你将看到mult (generic function with 1 method)

对于短函数,还有一种更紧凑、单行的函数语法(赋值形式),例如,mult(x, y) = x * y。对于简单的单行函数力荐使用这种方式,因为它会代码更加清晰。因此,数学函数也可以写成更直观形式:f(x, y) = x^3 - y + x * y; f(3, 2) #=> 31.

函数定义了自己的范围;函数内声明的变量、传入的参数,都只可在函数内访问。函数可被定义为顶层(全局)或嵌套(定义在另外一个函数内部)。通常,具有相关连特性的函数被放到同一个Julia 文件中,然后该文件一个主文件引用。或者,如果函数忒大,它可以放在一个单独的文件里,并且最好文件名即函数名。

results matching ""

    No results matching ""