1

我正在 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并有方法来解释三种可能的情况。

  1. 用户length在调用时指定f
  2. 用户step在调用时指定f
  3. 用户在调用时既不指定length也不指定,因此使用默认值。stepfstep

我宁愿不创建更多的方法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
4

1 回答 1

2

range函数在未指定时使用nothingfor step/ ,因此以下内容应该适合您:length

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

我宁愿不创建更多的 f 方法以避免过度复制 #do more stuff with x 和 r

一种比较常见的模式是将核心功能移至另一个函数,例如_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
于 2020-05-08T08:21:11.690 回答