我如何从另一个函数中将关键字参数传递给 `range` 函数,并使用 Julia 保持用户的灵活性?
How can I pass keyword arguments to the `range` function from within another function and maintain user flexibility with Julia?
我正在用 Julia 编写我的第一个模块。我有一个函数 f
,它将使用向量或范围进行某些计算。我想创建一个此函数的方法,它将在继续计算之前使用 range
函数创建一个范围,以便为用户提供一些灵活性。
我写了以下内容:
# Attempt 1
function f(x,start,stop;length=1001,step=0.1)
r=range(start,stop,length=length,step=step)
# do more stuff with x and r
end
# error: length and step don't agree
但是,range
将只接受 step
或 length
之一。除非它们被一致定义,否则它不能同时采用两者。这导致我想要定义另一个函数 g
,它将在 f
内部调用。 g
会调用 range
并有方法来解释三种可能的情况。
- 用户在调用
f
时指定length
。
- 用户在调用
f
时指定step
。
- 用户在调用
f
时既未指定 length
也未指定 step
,因此使用默认值 step
。
我不想创建更多 f
的方法以避免过度复制 #do more stuff with x and r
。我还想尽可能避免使用 if
语句,以利用多重分派并提高效率。虽然,到目前为止我还没有想出任何解决方案。
我无法使用关键字参数定义 g
的多个方法,因为关键字参数是可选的。
# Attempt 2
function g(start,stop;length=1001)
r=range(start,stop,length=length)
end
function g(start,stop;step=0.1)
r=range(start,stop,step=step)
end
# error: the method definitions overlap
我也无法将关键字参数转换为常规参数,因为我不知道要传递哪个参数。
# Attempt 3
function g(start,stop,length)
r=range(start,stop,length=length)
end
function g(start,stop,step)
r=range(start,stop,step=step)
end
function f(x,start,stop;length=1001,step=0.1)
r=g(start,stop,y)
end
# error: no way to determine y or to differentiate length from step when passed to g
range
函数在 step
/length
未指定时使用 nothing
,因此以下内容应该适用于您:
function f(start, stop; step=nothing, length=nothing)
if step === length === nothing
step = 0.1 # default step
end
r = range(start, stop; step=step, length=length)
return r
end
示例:
julia> f(1, 2; step=0.2)
1.0:0.2:2.0
julia> f(1, 2; length=3)
1.0:0.5:2.0
julia> f(1, 2) # default step
1.0:0.1:2.0
I'd rather not create more methods of f to avoid copying #do more
stuff with x and r excessively
一个比较常见的模式是将核心功能移动到另一个函数,比如 _f
,并有多个入口点 f
,它们为 _f
构造正确的参数。这是草图:
function f(x, y)
# construct arguments with x and y
args = ...
return _f(args...)
end
function f(x, y, z)
# construct arguments with x, y and z
args = ...
return _f(args...)
end
function _f(args...)
# core computation
end
我正在用 Julia 编写我的第一个模块。我有一个函数 f
,它将使用向量或范围进行某些计算。我想创建一个此函数的方法,它将在继续计算之前使用 range
函数创建一个范围,以便为用户提供一些灵活性。
我写了以下内容:
# Attempt 1
function f(x,start,stop;length=1001,step=0.1)
r=range(start,stop,length=length,step=step)
# do more stuff with x and r
end
# error: length and step don't agree
但是,range
将只接受 step
或 length
之一。除非它们被一致定义,否则它不能同时采用两者。这导致我想要定义另一个函数 g
,它将在 f
内部调用。 g
会调用 range
并有方法来解释三种可能的情况。
- 用户在调用
f
时指定length
。 - 用户在调用
f
时指定step
。 - 用户在调用
f
时既未指定length
也未指定step
,因此使用默认值step
。
我不想创建更多 f
的方法以避免过度复制 #do more stuff with x and r
。我还想尽可能避免使用 if
语句,以利用多重分派并提高效率。虽然,到目前为止我还没有想出任何解决方案。
我无法使用关键字参数定义 g
的多个方法,因为关键字参数是可选的。
# Attempt 2
function g(start,stop;length=1001)
r=range(start,stop,length=length)
end
function g(start,stop;step=0.1)
r=range(start,stop,step=step)
end
# error: the method definitions overlap
我也无法将关键字参数转换为常规参数,因为我不知道要传递哪个参数。
# Attempt 3
function g(start,stop,length)
r=range(start,stop,length=length)
end
function g(start,stop,step)
r=range(start,stop,step=step)
end
function f(x,start,stop;length=1001,step=0.1)
r=g(start,stop,y)
end
# error: no way to determine y or to differentiate length from step when passed to g
range
函数在 step
/length
未指定时使用 nothing
,因此以下内容应该适用于您:
function f(start, stop; step=nothing, length=nothing)
if step === length === nothing
step = 0.1 # default step
end
r = range(start, stop; step=step, length=length)
return r
end
示例:
julia> f(1, 2; step=0.2)
1.0:0.2:2.0
julia> f(1, 2; length=3)
1.0:0.5:2.0
julia> f(1, 2) # default step
1.0:0.1:2.0
I'd rather not create more methods of f to avoid copying #do more stuff with x and r excessively
一个比较常见的模式是将核心功能移动到另一个函数,比如 _f
,并有多个入口点 f
,它们为 _f
构造正确的参数。这是草图:
function f(x, y)
# construct arguments with x and y
args = ...
return _f(args...)
end
function f(x, y, z)
# construct arguments with x, y and z
args = ...
return _f(args...)
end
function _f(args...)
# core computation
end