我认为有一种更惯用的方法,不需要宏或任何其他包。文档建议使用最惯用的方法,例如 Matrix factorization 的文档。
尤其是这一行:
julia> l, u, p = lu(A); # destructuring via iteration
这表明迭代是正确的方法。所以剩下的就是让你的结构实现iteration interface
一个非常简单但不惯用的例子:
你的结构看起来像这样
struct MyModel
a::Int = 5
b::Float64 = 5.5
c::Matrix{Float64} = rand(3,4)
# 40 other parameters go here
end
要实现迭代接口,您需要定义Base.iterate,它将MyModel 作为参数和“状态”。该函数返回与状态对应的元素,并调用下一次迭代(有点像链表)。例如:
function Base.iterate(m::MyModel, state)
if state == 1
return(m.a, state+1)
elseif state == 2
return(m.b, state+1
elseif state == 3
return(m.c, state+1)
else
return nothing
end
end
在 julia 中,当 next(iter) == nothing 时迭代停止,这就是为什么当没有任何东西可以迭代时你必须返回 nothing。
高级示例
您可以在source code 中找到一个更惯用(但做作)的示例,用于lu 分解:
# iteration for destructuring into components
Base.iterate(S::LU) = (S.L, Val(:U))
Base.iterate(S::LU, ::Val{:U}) = (S.U, Val(:p))
Base.iterate(S::LU, ::Val{:p}) = (S.p, Val(:done))
Base.iterate(S::LU, ::Val{:done}) = nothing
如果我没记错的话,它使用Val 进行一些编译时优化。
在具有 40 个字段的结构的特殊情况下,我想不出更符合人体工程学的方式,也许数据更适合另一种存储选项。