Julia 以编程方式将参数传递给@kwdef struct 以编程方式将参数传递给@kwdef struct 问题

Julia 以编程方式将参数传递给@kwdef struct 以编程方式将参数传递给@kwdef struct 问题,julia,Julia,我有这个结构: Base.@kwdef struct example_struc Latitude::Float64 = 9.9 # Latitude (degree) Longitude::Float64 = -83.7 # Longitude (degree) end @kwdef允许我实例化一个示例_struc(),由于默认设置,我不需要给出所有参数,例如: 我希望通过将参数的名称及其值传递给example\u struc以编程方式(从文件中读取

我有这个结构:

Base.@kwdef struct example_struc
    Latitude::Float64  = 9.9        # Latitude (degree)
    Longitude::Float64 = -83.7      # Longitude (degree)
end
@kwdef允许我实例化一个
示例_struc()
,由于默认设置,我不需要给出所有参数,例如:

我希望通过将参数的名称及其值传递给
example\u struc
以编程方式(从文件中读取的元组)实例化它

我试过的 什么有效 我可以使用如下元编程为一个参数执行此操作:

# Named tuple usually read from a file:
params= (Latitude = 43.61, Longitude = 3.877)
params_names= collect(keys(params))
e
看起来像这样的
:(示例结构(纬度=43.61))
,而
a
与之前完全相同

什么不起作用 现在在我的例子中,参数的数量超过两个(最多50个),所以我需要能够同时对多个参数执行此操作。 因此,我尝试使用map作为一个整体传递函数参数:

b= map((x,y) -> :($x = $y),params_names,params)
f= :(example_struc($(b...)))
eval(f)
f
如下所示:
:(例如,纬度=43.61,经度=3.877))
它是有效的,但只是因为我们传递了所有参数:我们没有使用默认值

现在,如果我想使用
经度的默认值,它不起作用:

b= map((x,y) -> :($x = $y),[params_names[1]],[params[1]])
f= :(example_struc($(b...)))
eval(f)
f
如下所示:
:(示例结构(纬度=43.61))
但是现在有一个错误:
error:MethodError:no方法匹配示例结构(::Float64)

因此,它不是像我期望的那样调用函数:
example\u struc(Latitude=43.61)
,而是这样调用它:
example\u struc(43.61)
,不带参数名

你知道怎么解决这个问题吗?我对任何解决方案都持开放态度,包括改变用户提供输入的方式(但必须简单)

更多背景 我正在用Julia编写一个程序,它读取一个可能包含Julia代码的用户输入文件(这是安全的,因为用户只在本地使用它)。因此,输入文件本身是一个.jl文件,使用
evalfile
进行评估,用户以元组形式提供参数值,例如:

(
 Latitude::Float64  = 9.9,        # Latitude (degree)
 Longitude::Float64 = -83.7       # Longitude (degree)
 some_function= x -> x + 2        # Some functions can be defined by the user (if not, we use the default definition)
)

我的程序读取元组,我想提供一些默认值,例如,如果用户只输入
纬度
,程序将使用默认的
经度
和默认的
某些函数
。为此,我使用@kwdef结构来利用其默认功能,但我需要知道如何以编程方式传递参数

您应该能够将命名元组解压到构造函数的关键字参数位置。下面是一个简单的例子:

julia> Base.@kwdef struct A
           x::Int64 = 1
           y::Int64 = 2
           z::Int64 = 3
       end
A

julia> kwargs = (z = 5, y = 4)
(z = 5, y = 4)

julia> A(; kwargs...)
A(1, 4, 5)
请注意,您需要在函数调用中使用分号来指示未打包的参数是关键字参数。如果没有分号,将出现方法错误:

julia> A(kwargs...)
ERROR: MethodError: no method matching A(::Int64, ::Int64)
Closest candidates are:
  A(::Int64, ::Int64, ::Int64) at REPL[13]:2
  A(::Any, ::Any, ::Any) at REPL[13]:2
Stacktrace:
 [1] top-level scope at none:0
有关关键字参数的详细信息

julia> Base.@kwdef struct A
           x::Int64 = 1
           y::Int64 = 2
           z::Int64 = 3
       end
A

julia> kwargs = (z = 5, y = 4)
(z = 5, y = 4)

julia> A(; kwargs...)
A(1, 4, 5)
julia> A(kwargs...)
ERROR: MethodError: no method matching A(::Int64, ::Int64)
Closest candidates are:
  A(::Int64, ::Int64, ::Int64) at REPL[13]:2
  A(::Any, ::Any, ::Any) at REPL[13]:2
Stacktrace:
 [1] top-level scope at none:0