最好通过一个例子来解释:
我定义了一个类型
type myType
α::Float64
β::Float64
end
z = myType( 1., 2. )
然后假设我想将此类型作为参数传递给函数:
myFunc( x::Vector{Float64}, m::myType ) =
x[1].^m.α+x[2].^m.β
有没有办法传递myType
,以便我可以以“更干净”的方式在函数体中实际使用它,如下所示:
x[1].^α+x[2].^β
感谢您的回答。
答案 0 :(得分:7)
一种方法是将调度用于更通用的功能:
myFunc( x::Vector{Float64}, α::Float64, β::Float64) = x[1].^α+x[2].^β
myFunc( x::Vector{Float64}, m::myType = myFunc(x,m.α,m.β)
或者如果您的功能较长,您可能需要使用Parameters.jl的@unpack
:
function myFunc( x::Vector{Float64}, m::myType )
@unpack m: α,β #now those are defined
x[1].^α+x[2].^β
end
解压缩的开销很小,因为你没有复制,它只是做了一堆α=m.α
而只是使α
指向m.α
。对于较长的方程式,如果你有很多字段并在长时间计算中使用它们,这可能是一个更好的形式(作为参考,我在DifferentialEquations.jl中经常使用它。)
评论中提到了另一种方式。让我说明一下。您可以使用Parameters.jl中的@with_kw
宏来定义类型(使用可选的kwargs)。例如:
using Parameters
@with_kw type myType
α::Float64 = 1.0 # Give a default value
β::Float64 = 2.0
end
z = myType() # Generate with the default values
然后您可以使用由@unpack_myType
宏自动生成的@with_kw
宏:
function myFunc( x::Vector{Float64}, m::myType )
@unpack_myType m
x[1].^α+x[2].^β
end
同样,这只会产生无需复制的参考α和β的开销,所以它非常轻量级。
答案 1 :(得分:1)
您可以将其添加到您的函数正文中:
(α::Float64, β::Float64) = (m.α, m.β)
答案 2 :(得分:1)
更新:我的原始答案出于一个微妙的原因是错误的,但我认为这是一个非常有趣的信息,所以不要完全删除它,我会留下一个解释为什么这是不对的。非常感谢凤阳指出全球范围内的评价! (以及在Expr上下文中使用$
!)
原始答案提出:
[eval( parse( string( i,"=",getfield( m,i)))) for i in fieldnames( m)]
将返回具有赋值副作用的列表推导,因为它在概念上会产生类似[α=1., β=2., etc]
的内容。假设这项任务将在当地范围内。但是,正如所指出的那样,eval
始终在全局范围内进行评估,因此上述单行内容并不符合其意图。例如:
julia> type MyType
α::Float64
β::Float64
end
julia> function myFunc!(x::Vector{Float64}, m::MyType)
α=5.; β=6.;
[eval( parse( string( i,"=",getfield( m,i)))) for i in fieldnames( m)]
x[1] = α; x[2] = β; return x
end;
julia> myFunc!([0.,0.],MyType(1., 2.))
2-element Array{Float64,1}:
5.0
6.0
julia> whos()
MyType 124 bytes DataType
myFunc 0 bytes #myFunc
α 8 bytes Float64
β 8 bytes Float64
即。正如你所看到的,意图是局部变量α和β被覆盖,但它们没有; eval将α和β变量放在全局范围内。作为一名matlab程序员,我天真地认为eval()
在概念上等同于Matlab,没有实际检查。事实证明它更像evalin('base',...)
命令。
再次感谢Fengyand提供另一个例子,说明为什么短语“parse and eval”似乎与Julia程序员在the knights who until recently said "NI"上的单词“it”具有相同的效果。 :)