我有一个代表要调用的函数名称的符号:
julia> func_sym = :tanh
我可以使用该符号来获取tanh函数并使用:
调用它julia> eval(func_sym)(2)
0.9640275800758169
但我宁愿避免使用'eval',因为它会被多次调用而且价格昂贵(而且func_sym可能有几个不同的值,具体取决于上下文)。
Ruby中的IIRC你可以这样说:
obj.send(func_sym, args)
朱莉娅有类似的东西吗?
编辑:有关为什么我有符号表示函数的更多细节:
我有一个包含激活功能的类型(来自神经网络),最初我把它作为一个功能包括在内:
type NeuralLayer
weights::Matrix{Float32}
biases::Vector{Float32}
a_func::Function
end
但是,我需要使用JLD将这些内容序列化为文件,但是无法序列化函数,所以我选择了符号:
type NeuralLayer
weights::Matrix{Float32}
biases::Vector{Float32}
a_func::Symbol
end
目前我使用上面的eval方法来调用激活功能。有一些NeuralLayers集合,每个都可以拥有它自己的激活功能。
答案 0 :(得分:7)
@ Isaiah的回答是正确的;在编辑原始问题之后,或许更是如此。要详细说明并使其更具针对您的案例:我将您的NeuralLayer
类型更改为参数化:
type NeuralLayer{func_type}
weights::Matrix{Float32}
biases::Vector{Float32}
end
由于func_type
未出现在字段类型中,因此构造函数将要求您明确指定它:layer = NeuralLayer{:excitatory}(w, b)
。这里的一个限制是您无法修改类型参数。
现在,func_type
可能是一个符号(就像你现在正在做的那样),或者它可能是一个功能更相关的参数(或参数)来调整你的激活功能。然后你定义你的激活函数:
# If you define your NeuralLayer with just one parameter:
activation(layer::NeuralLayer{:inhibitory}) = …
activation(layer::NeuralLayer{:excitatory}) = …
# Or if you want to use several physiological parameters instead:
activation{g_K,g_Na,g_l}(layer::NeuralLayer{g_K,g_Na,g_l} = f(g_K, g_Na, g_l)
关键是功能和行为是外部到数据。使用类型定义和抽象类型层次结构来定义行为,如在外部函数中编码的那样......但仅在类型中存储数据本身。这与Python或其他强烈面向对象的范例截然不同,需要一些时间来习惯。
答案 1 :(得分:4)
但我宁愿避免使用'eval',因为它会被多次调用而且价格昂贵(而且func_sym可能有几个不同的值,具体取决于上下文)。
这种动态调度在Julia中是可行的,但不推荐。根据上下文更改'func_sym'的值会导致类型推断以及方法特化和内联失败。相反,建议的方法是使用multiple dispatch,详见手册的Methods部分。