【问题标题】:Dispatching on arguments after the slurping operator (args...) in julia在 julia 中的 slurping 运算符 (args...) 之后调度参数
【发布时间】:2022-01-21 04:35:20
【问题描述】:

你将如何实现这样的功能:

function foo(a,b...,c)
    println(a,b,c)
end
foo(2,3,3,"last")

=> a = 2 , b = (3,3) , c = "最后一个"

我不能使用类似的东西:

function foo(a,b...) 
    c = b[end]
    println(a,b,c)
end

因为我想在 c 上调度, IE。 我想要方法:

foo(a,b...,c::Foo)

foo(a,b...,c::Bar)

我也不能有这样的东西:

foo_wrapper(a,b...) = foo(a,b[1:end-1],b[end])

因为我也想在 foo 上进行调度。

这可能吗?

【问题讨论】:

  • 不,这目前是不可能的。请参阅github.com/JuliaLang/julia/issues/42036#issuecomment-909923031 了解其中的一些困难。
  • 您所说的“一般在 foo 上”调度是什么意思?因为您可以为 foo(a::Yada, c::Blah, b...) 创建多个基于 a 和 c 调度 foo 的方法,然后编写单个方法 foo_wrapper(a,b...) = foo(a, b[end], b[1:end-1]) 来重新排序 foo 的参数。

标签: function julia multiple-dispatch


【解决方案1】:

您可以颠倒顺序,然后在辅助函数上分派:

function foo(a,d...)
    c = last(d)
    b = d[begin:end-1]
    return _foo(a,c,b...)
end

function _foo(a,c::Int,b...)
    return c+1
end

function _foo(a,c::Float64,b...)
    return 2*c
end

在 REPL 中:

julia> foo(1,2,3,4,5,6)
7
julia> foo(1,2,3,4,5,6.0)
12.0

julia> foo(1,2,8.0)
16.0

julia> foo(1,90) #b is of length zero in this case
91

【讨论】:

    【解决方案2】:

    唯一的选择是将c 作为关键字参数,例如:

    function foo(a,b...;c)
        println(a," ",b," ",c)
    end
    

    现在你可以这样做了:

    julia> foo(1,2,3;c="aa")
    1 (2, 3) aa
    

    【讨论】:

    • 不能在关键字参数上分派,因为位置顺序对于明确分派至关重要,关键字参数的全部意义在于通过名称而不是位置来指定。但是,带有关键字参数cfoo_wrapper 可以调用将c 作为位置参数的方法foo。但是,我不知道类型推断是否可以通过`foo_wrapper` 在编译时对c 的类型进行foo 的调度。 docs.julialang.org/en/v1/manual/methods/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-20
    • 2017-10-12
    • 2014-08-21
    • 1970-01-01
    • 2018-06-24
    • 1970-01-01
    • 2017-02-01
    相关资源
    最近更新 更多