在两个文件中重载函数(在Julia中)
我会用一个简单的例子来解释我的问题。假设我有三个文件: A.jl B.jl Main.jl在两个文件中重载函数(在Julia中),julia,multiple-dispatch,Julia,Multiple Dispatch,我会用一个简单的例子来解释我的问题。假设我有三个文件: A.jl B.jl Main.jl using A using B main = function() x = Atype() f(x) end main() 这里我有两个版本的f函数。如果我正确理解了多重分派的概念,那么应该在运行时扣除应该使用的版本。因此,我希望运行Main.jl会打印用调用的f。不幸的是,我 $ julia Main.jl ERROR: type: anonymous: in type
using A
using B
main = function()
x = Atype()
f(x)
end
main()
这里我有两个版本的f
函数。如果我正确理解了多重分派的概念,那么应该在运行时扣除应该使用的版本。因此,我希望运行Main.jl会打印用调用的f。不幸的是,我
$ julia Main.jl
ERROR: type: anonymous: in typeassert, expected Btype, got Atype
in include at /usr/bin/../lib64/julia/sys.so
in process_options at /usr/bin/../lib64/julia/sys.so
in _start at /usr/bin/../lib64/julia/sys.so
while loading /home/grzes/julia_sucks/Main.jl, in expression starting on line 9
如果我用B注释掉,效果很好。显然,B.jl中的f
重写了A.jl中的f
所以,问题是:问题出在哪里?在我的方法中,还是在我使用的Julia版本(0.3.7)中?我怎样才能避免这种情况
请注意,将使用
替换为导入A
并使用完全限定名(例如A.f
)不是一个好的解决方案。它与多重分派的关键相矛盾——在编译时,我不知道是应该使用A.f
还是B.f
,您必须使A.f
和B.f
具有相同的函数(在上面的示例中,它们只是同名的不同函数)。然后您可以在每个模块中重载一个方法,多个分派将完成它的工作
实现这一点的方法是,在使用新方法扩展之前,让其中一个模块从另一个模块导入函数f
(例如import A.f
inB
),或者使用A
和B
导入的f
函数添加第三个模块C
(您可以使用伪签名,如f(::Union())=nothing
,该签名在不添加任何实际方法的情况下从不应用于创建函数)
function A.f(x::Atype)
println("f called with A")
end
这将使Julia理解两个f
引用相同的概念,并且它们实际上在两个模块中都是相同的对象。添加一个方法会修改泛型函数对象,因此这种更改在使用f
的任何地方都可见。这是否意味着“泛型函数”有自己的作用域?例如,A.f()是模块A作用域中唯一通用的函数?谢谢!但是我花了一段时间才注意到我应该使用importall C
,而不是使用C
:)绑定有作用域,而不是值(对象)。泛型函数是一个(可变)值,本质上不属于任何范围。但是,如果尝试向当前作用域中不存在的函数f
添加方法,Julia将隐式创建一个新的泛型函数对象,并在当前作用域中的名称f
下为其创建绑定。但是,如果您将其导入到另一个模块,它与原始模块一样属于该模块。请使用特定导入(例如import a.f
)而不是importall
,这样可以避免一些意外的副作用。或者直接用A.f(x)=…
扩展A.f,例如A.f
。
$ julia Main.jl
ERROR: type: anonymous: in typeassert, expected Btype, got Atype
in include at /usr/bin/../lib64/julia/sys.so
in process_options at /usr/bin/../lib64/julia/sys.so
in _start at /usr/bin/../lib64/julia/sys.so
while loading /home/grzes/julia_sucks/Main.jl, in expression starting on line 9
function A.f(x::Atype)
println("f called with A")
end