3

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

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

主要.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,它工作正常。显然,f从 B.jl 覆盖f了从 A.jl。

所以,问题是:问题出在哪里?在我的方法中还是在我使用的 Julia 版本中(0.3.7)?我该如何规避这个?

请注意,替换using Aimport A使用完全限定名称(例如A.f)不是一个好的解决方案。它与多重分派的症结相矛盾——在编译时我不知道是否应该使用A.for B.f

4

1 回答 1

7

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

实现这一点的方法是让一个模块在使用新方法扩展它之前f从另一个模块(例如import A.fin )导入函数,或者添加第三个模块,该模块具有同时导入的函数(您可以使用虚拟签名像这样在不添加任何实际方法的情况下永远适用于创建函数)。我们直接从另一个模块扩展功能,如BCfABf(::Union()) = nothing

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

这将使 Julia 明白两者f指的是同一个概念,并且它们实际上是两个模块中的同一个对象。添加方法会修改泛型函数对象,因此此更改将在使用的任何地方可见f

于 2015-05-14T05:12:58.930 回答