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