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

时间:2015-05-14 02:23:07

标签: julia multiple-dispatch

我将以最小的例子解释我的问题。假设我有三个文件:

A.jl

module A

export Atype, f

type Atype  
end

f = function(x::Atype)
    println("f called with A")
end
end #module

B.jl

module B

export Btype, f

type Btype  
end

f = function(x::Btype)
    println("f called with B")
end
end #module

Main.jl

 using A
 using B

 main = function()
    x = Atype()
    f(x)
 end

 main()

这里我有两个版本的f函数。如果我理解正确的多次发送的想法,应该在运行时期间扣除应该使用哪个版本。因此,我预计运行Main.jl会打印f called with A。不幸的是,我得到了

$ 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

如果我评论using B,它就可以了。很明显,来自B.jl的f覆盖了来自A.jl的f

所以,问题是:问题出在哪里?在我的方法或Julia的版本中,我使用(0.3.7)?我怎么能绕过这个?

请注意,将using A替换为import A并使用完全限定名称(例如A.f)并不是一个好方法。它与多次发送的关键点相矛盾 - 在编译时我不知道是否应该使用A.fB.f

1 个答案:

答案 0 :(得分:6)

您必须使A.fB.f具有相同的功能(在上面的示例中,它们只是具有相同名称的不同功能)。然后你可以在每个模块中重载一个方法,多个调度将完成它的工作。

实现此目的的方法是让其中一个模块从另一个模块导入函数f(例如import A.f中的B),然后再使用新方法扩展它,或者添加第三个模块C,其中包含fA导入的B函数(您可以使用永远不会创建的f(::Union()) = nothing虚拟签名功能,无需添加任何实际方法)。我们直接从其他模块扩展功能,如

function A.f(x::Atype)
    println("f called with A")
end

这将使Julia明白两个f引用相同的概念,它们实际上是两个模块中的同一个对象。添加方法会修改通用函数对象,因此在使用f的任何位置都可以看到此更改。