Julia函数键值参数

Julia键值参数

对于控制逻辑复杂的函数,往往需要大量的输入参数。此时的参数列表一般很长,维护起来并不容易。尤其是对这种函数调用的时候,因为参数表有序,所以只能按序提供输入值,偶尔出现的乱序问题经常会给开发带来不小麻烦。即便在定义中尽可能多地提供默认值,但仍然治标不治本。

典型的例子是图表绘制的plot函数,其中可能需要线型、宽度、颜色、箭头形式、图例位置、坐标轴情况等等繁杂的控制参数。在调用时,不同的图表会需要配置不同的参数并忽略其他参数;但因为默认参数必须在参数表尾部,所以无法无序地跳跃设定仅需的参数。而且参数列表很长也会导致调用处的实参值列表变得很长,在修改维护时很难区分与参变量的对应关系。

如果传参时带有参数的名字,便可更为直观地知道提供的是哪个参数值;

如果能够借鉴前面介绍的字典的结构,便可让参数表具备无序性和直观性的特点,即按键名跳着配置仅需的参数。Julia提供了这种“键值对”设置参数的方式,此时函数头的一般形式为:

函数名(有序参数表;键名1=值1, 键名2=值2, ...)

或可同时限定类型:

函数名(有序参数表;键名1::类型1=值1, 键名2::类型2=值2, ...)

其中,“键名i=值i”便是键值参数(Keyword Arguments),以“键名i”为参数名,“值i”是该参数的默认值。这种键值参数的特性类似于Pair类型,显然,默认值是不可少的,必须提供。

函数定义时,键值参数表需在已有的有序参数表之后,两者间需以英文分号区分。有序参数表可以没有,但分割用的分号不可省略,即:

函数名(; 键名1=值1, 键名2=值2, ...)

这是因为如果分号省略,键值部分便成了带有默认值的有序参数表了。

对使用了键值参数的函数进行调用,有两种可选方式:

函数名(有序实参表,键名1=值1, 键名2=值2, ...)     # 有序实参表后为逗号
函数名(有序实参表;键名1=值1, 键名2=值2, ...)     # 有序实参表后为分号

显然,键值对是无序的,而且可以在调用时不提供不需要的参数。但提供的参数必须同时带有键名,即需以Pair形式配置。同样,若有序实参表缺失,则只能采用分号形式且分号不可少。如果同时存在可变参数,也只能使用分号形式。

另外,调用时也可采用Pair方式提供键值参数,但键名(参数名)需以Symbol类型输入,即在名字前加冒号:标识符(后文介绍),即:

函数名(有序实参表; :键名1=>值1,  :键名2=>值2, …)

注意,此时必须使用分号形式。

下面,我们仍以绘图plot()函数为例,说明键值参数的用法。定义如下:

julia> function plot(x, y; style="solid", width=1, color="black")
          print("ok")
        end
plot (generic function with 1 method)

提供所有的参数进行调用,代码如下:

julia> plot(1, 2, width=30, style="solid", color="black")       # 逗号分隔方式
ok
# Pair方式,且未按顺序提供键值参数的值
julia> plot(1, 2; :color=>"black", :style=>"solid", :width=>30)
ok

其中提供的键值参数并没有遵循定义的顺序。或者,完全不提供键值实参,例如:

julia> plot(1, 2)
ok

当然,只提供部分键值参数也是可以的:
Julia键值参数

所以,提供键值参数时不必依序,可任意地选择某个感兴趣的键值参数进行配置。

需要注意的是,在传递的键值实参列表中如果存在重复键值对,会抛出异常。例如:
Julia键值参数

还有一种情况,在函数定义时,键值参数使用了表达式,而且后一键值的默认值表达式中出现了前面的键名。此时,在该默认值计算时,会将表达中出现的键名作变量处理,且各变量的取值为对应的默认值。例如:

julia> function bar(; x=1, y=x+3, z=x+y)
          println("x=", x)
          println("y=", y)
          println("z=", z)
        end
bar (generic function with 1 method)

julia> bar(; x=1)            # y默认值由x+3计算出,z则有x与计算后的y累加
x=1
y=4
z=5

julia> bar(; x=1, z=10)     # 因z提供了值,故其默认计算的结果被替代
x=1
y=4
z=10

酷客网相关文章:

赞(0)

评论 抢沙发

评论前必须登录!