我正在研究一个Julia函数,该函数在闭包内部构造具有多个方法的函数并将其返回。为了简化(实际构造涉及多个非平凡的自定义类型),它看起来像这样:

function constructF(g::Function, n::Int)

    v = [g]
    for i in 2:n
        gi(x) = ForwardDiff.derivative(v[i - 1], x)
        v = vcat(v, gi)
    end

    for T in (Int, Float64) # two types but possibly more
        function f(x::T)
            acc = T(0)
            for i in 1:n
                acc += v[i](x)^i
            end
            acc
        end
    end

    return f
end

从Julia 1.1.1开始不支持这种代码,这给了我
ERROR: LoadError: syntax: local variable T cannot be used in closure declaration
Stacktrace:
 [1] include(::String) at ./client.jl:403
 [2] top-level scope at none:0
in expression starting at /home/me/code/lang/julia/test.jl:3

替代方法如下所示,但会导致代码重复。
function constructF(n::Int)

    v = [g]
    for i in 2:n
        gi(x) = ForwardDiff.derivative(v[i - 1], x)
        v = vcat(v, gi)
    end

    function f(x::Int)
        acc = Int(0)
        for i in 1:n
            acc += v[i](x)^i
        end
        acc
    end

    function f(x::Float64)
        acc = Float64(0)
        for i in 1:n
            acc += v[i](x)^i
        end
        acc
    end

    # ....

    return f
end

有没有更好的方法来写这个?我已经研究了元编程,但是文档看起来很不直观,我不确定如何在这里应用它。

最佳答案

我只是回答了我自己的问题。通过一些基本的元编程,我可以做到:

function constructF(g::Function, n::Int)

    v = [g]
    for i in 2:n
        gi(x) = ForwardDiff.derivative(v[i - 1], x)
        v = vcat(v, gi)
    end

    for T in (:Int, :Float64)
        @eval function f(x::$T)
            acc = $T(0)
            for i in 1:$n
                acc += $v[i](x)^i
            end
            acc
        end
    end

    return f
end

创建一个Julia表达式,并使用Int,Float64等每种类型对其进行求值。

关于types - 在闭包内部构造具有多个方法的函数,并且出现错误“语法:闭包声明中不能使用局部变量T”,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57367055/

10-14 14:34
查看更多