在两个文件中重载一个函数(在 Julia 中)
Posted
技术标签:
【中文标题】在两个文件中重载一个函数(在 Julia 中)【英文标题】:Overloading a function in two files (in Julia) 【发布时间】:2015-07-25 12:50:46 【问题描述】:我将用一个最小的例子来解释我的问题。假设我有三个文件:
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.f
还是B.f
。
【问题讨论】:
【参考方案1】:您必须使A.f
和B.f
具有相同的功能(在上面的示例中,它们只是具有相同名称的不同功能)。然后,您可以在每个模块中重载一个方法,并且多个分派将完成其工作。
实现这一点的方法是让一个模块从另一个模块导入函数f
(例如B
中的import A.f
),然后用新方法扩展它,或者添加第三个模块@987654326 @ 带有 A
和 B
导入的 f
函数(您可以使用像 f(::Union()) = nothing
这样的虚拟签名,它在不添加任何实际方法的情况下永远适用于创建函数)。我们直接从其他模块扩展功能,如
function A.f(x::Atype)
println("f called with A")
end
这会让 Julia 明白这两个f
指的是同一个概念,它们实际上在两个模块中都是同一个对象。添加一个方法会修改通用函数对象,因此在使用f
的任何地方都可以看到此更改。
【讨论】:
这是否意味着“通用函数”有自己的范围?例如,A.f() 是一个仅在模块 A 范围内通用的函数? 为我工作,谢谢!但是我花了一段时间才注意到我应该使用importall C
而不是 using C
:)
绑定有范围,而不是值(对象)。泛型函数是一个(可变)值,本质上不属于任何范围。但是,如果您尝试将方法添加到当前作用域中不存在的函数 f
,则 Julia 将隐式创建一个新的泛型函数对象,并在当前作用域中以名称 f
为其创建绑定.但是如果你将它导入另一个模块,它就和原来的模块一样。
请使用特定的导入(例如import A.f
)而不是importall
,它往往会避免一些意想不到的副作用。或者直接用A.f(x) = ...
扩展例如A.f
。以上是关于在两个文件中重载一个函数(在 Julia 中)的主要内容,如果未能解决你的问题,请参考以下文章