当前位置:K88软件开发文章中心编程语言非主流编程语言Julia → 文章内容

Julia 函数

减小字体 增大字体 作者:佚名  来源:网上搜集  发布时间:2019-1-15 16:28:08

的可迭代的参数集合,其参数个数为 0 或多个:julia> bar(1,2)(1,2,())julia> bar(1,2,3)(1,2,(3,))julia> bar(1,2,3,4)(1,2,(3,4))julia> bar(1,2,3,4,5,6)(1,2,(3,4,5,6)) 上述例子中, x 是传递给 bar 的尾随的值多元组。 函数调用时,也可以使用 ... :julia> x = (3,4)(3,4)julia> bar(1,2,x...)(1,2,(3,4)) 上例中,多元组的值完全按照变参函数的定义进行内插,也可以不完全遵守其函数定义来调用:julia> x = (2,3,4)(2,3,4)julia> bar(1,x...)(1,2,(3,4))julia> x = (1,2,3,4)(1,2,3,4)julia> bar(x...)(1,2,(3,4)) 被内插的对象也可以不是多元组:julia> x = [3,4]2-element Array{Int64,1}: 3 4julia> bar(1,2,x...)(1,2,(3,4))julia> x = [1,2,3,4]4-element Array{Int64,1}: 1 2 3 4julia> bar(x...)(1,2,(3,4)) 原函数也可以不是变参函数(大多数情况下,应该写成变参函数):baz(a,b) = a + bjulia> args = [1,2]2-element Int64 Array: 1 2julia> baz(args...)3julia> args = [1,2,3]3-element Int64 Array: 1 2 3julia> baz(args...)no method baz(Int64,Int64,Int64) 但如果输入的参数个数不对,函数调用会失败。 可选参数 很多时候,函数参数都有默认值。例如,库函数 parseint(num,base) 把字符串解析为某个进制的数。base 参数默认为 10。这种情形可以写为:function parseint(num, base=10) ###end 这时,调用函数时,参数可以是一个或两个。当第二个参数未指明时,自动传递 10:julia> parseint("12",10)12julia> parseint("12",3)5julia> parseint("12")12 可选参数很方便参数个数不同的多方法定义(详见方法)。 关键字参数 有些函数的参数个数很多,或者有很多行为。很难记住如何调用这种函数。关键字参数,允许通过参数名来区分参数,便于使用、扩展这些复杂接口。 例如,函数 plot 用于画出一条线。此函数有许多可选项,控制线的类型、宽度、颜色等。如果它接收关键字参数,当我们要指明线的宽度时,可以调用 plot(x, y, width=2)之类的形式。这样的调用方法给参数添加了标签,便于阅读;也可以按任何顺序传递部分参数。 使用关键字参数的函数,在函数签名中使用分号来定义:function plot(x, y; style="solid", width=1, color="black") ###end 额外的关键字参数,可以像变参函数中一样,使用 ... 来匹配:function f(x; y=0, args...) ###end 在函数 f 内部,args 可以是 (key,value) 多元组的集合,其中 key 是符号。可以在函数调用时使用分号来传递这个集合, 如 f(x, z=1; args...). 这种情况下也可以使用字典。 关键字参数的默认值仅在必要的时候从左至右地被求值(当对应的关键字参数没有被传递),所以默认的(关键字参数的)表达式可以调用在它之前的关键字参数。 默认值的求值作用域 可选参数和关键字参数的区别在于它们的默认值是怎样被求值的。当可选的参数被求值时,只有在它之前的的参数在作用域之内; 与之相对的, 当关键字参数的默认值被计算时, 所有的参数都是在作用域之内。比如,定义函数:function f(x, a=b, b=1) ###end 在 a=b 中的 b 指的是该函数的作用域之外的 b ,而不是接下来 的参数 b。然而,如果 a 和 b 都是关键字参数,那么它们都将在 生成在同一个作用域上,a=b 中的 b 指向的是接下来的参数 b (遮蔽了任何外层空间的 b), 并且 a=b 会得到未定义变量的错误 (因为默认 参数的表达式是自左而右的求值的,b 并没有被赋值)。 函数参数的块语法 将函数作为参数传递给其它函数,当行数较多时,有时不太方便。下例在多行函数中调用 map :map(x->begin if x < 0 && iseven(x) return 0 elseif x == 0 return 1 else return x end end, [A, B, C]) Julia 提供了保留字 do 来重写这种代码,使之更清晰:map([A, B, C]) do x if x < 0 && iseven(x) return 0 elseif x == 0 return 1 else return x endend do x 的语法创建一个含有参数 x 的匿名函数,并将其传给 map 作为第一个参数。类似地,do a,b 将创建一个含有两个参数的匿名函数,和一个朴素的 do 的声明以 () -> .... 方式说明如下是一个匿名函数。 如何将这些参数初始化取决于“外部”函数;在这里,map 将依次设置 x 到 A, B, C,每个都将调用匿名函数,就像在语法 map(func, [A, B, C]) 中做的一样。 因为语法的调用看起来像正常的代码块,所以这种语法使它更容易使用函数来有效地扩展语言。这里有许多可能完全不同于 map 的用途,如管理系统状态。例如,有一个版本的 open,运行代码来确保打开的文件最终关闭:open("outfile", "w") do io write(io, data)end 它可以通过以下定义来实现:function open(f::Function, args...) io = open(args...) try f(io) finally close(io) endend 对比的 map 的例子,这里的 IO 是通过 open("outfile", "w")来实现初始化的。字符流之后会传递给您的执行写入的匿名函数;最后,open 的功能确保流在您的函数结束后是关闭状态的。 try/finally 的构造将在 控制流 中被描述。 do 块语法的使用有助于检查文档或实现了解用户函数的参数是如何被初始化的。

上一页  [1] [2] 


Julia 函数