我可以将关键字参数传递给 Julia 中的 do 块吗?

问题描述 投票:0回答:3

下面是一个例子:

def(f::Function) = f

f1 = def() do x
    x
end

f2 = def() do x, y
    x, y
end

f3 = def() do x, y; z # this syntax is accepted
    x, y, z
end

f1(1)
f2(1, 2)
f3(1, 2, z=3) # ERROR: LoadError: function #13 does not accept keyword arguments

下面的例子不是我的实际用例,但它说明了问题。我应该如何处理 do 块中的 kwargs?

julia
3个回答
5
投票

据我所知这是不可能的。如果你查看 /src/julia-parser.scm 文件,你会发现 do 块的解析是在

parse-do
here中定义的。您可以看到
do
块被重写为匿名函数,该函数只能接受
doargs
变量中以逗号分隔的位置参数。

this 行中,您可以看到

;
显式终止对
do
块的参数的解析。这意味着:

julia> z = "hello"
"hello"

julia> f3 = def() do x, y; println(z) # this syntax is accepted
           x, y, z
       end
#24 (generic function with 1 method)

julia> f3(100, 1000)
hello
(100, 1000, "hello")

将工作,因为

;
之后的代码被视为
do
块体的一部分。

您可以尝试将

(
)
放在参数周围,如下所示:

julia> f3 = def() do (x, y; z)
           x, y, z
       end
ERROR: syntax: invalid assignment location "; z"

julia> f3 = def() do (y; z)
           y, z
       end
ERROR: syntax: "begin
    y
    # REPL[52], line 1
    z
end" is not a valid function argument name

这将通过解析器,但随后 julia-syntax.scm 将抛出错误。这可能可以改进为:

f3 = def(function(x, y; z)
    x, y, z
end)

工作正常(您可以考虑在 https://github.com/JuliaLang/julia/issues 上为此打开一个问题)。

在解决此问题之前,您唯一能做的就是使用我上面给出的匿名函数定义方法(尽管它不是很干净)。


1
投票

你可以这样做,你只需要在

kwargs
之前传递
do

julia> f(g, xs; kwargs...) = begin
           println(kwargs...)
           map(g,xs)
       end
f (generic function with 1 method)

julia> f(1:5; thisworks=true) do x x^2 end
:thisworks => true
5-element Array{Int64,1}:
  1
  4
  9
 16
 25

0
投票

我想这就是你要找的.. 我使用一个小技巧通过 Julia 的 Do-Block 参数来封装关键字参数。

请参考: 我的 GitHub 答案 我的 GitHub 答案

© www.soinside.com 2019 - 2024. All rights reserved.