在两个文件中重载函数(在Julia中)

在两个文件中重载函数(在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

我会用一个简单的例子来解释我的问题。假设我有三个文件:

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 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
in
B
),或者使用
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