问题描述
我是 Julia 的新手,所以这可能是微不足道的.
I am new to Julia, so this might be trivial.
我在一个模块中有一个函数定义,看起来像(使用 URIParser):
I have a function definition within a module that looks like (using URIParser):
function add!(graph::Graph,
subject::URI,
predicate::URI,
object::URI)
...
end
在模块之外,我调用:
add!(g, URIParser.URI("http://test.org/1"), URIParser.URI("http://test.org/2"), URIParser.URI("http://test.org/1"))
这给了我这个错误:
ERROR: no method add!(Graph,URI,URI,URI)
in include at boot.jl:238
in include_from_node1 at loading.jl:114
at /Users/jbaran/src/RDF/src/RDF.jl:79
很奇怪.因为当我可以看到匹配的签名时:
Weird. Because when I can see a matching signature:
julia> methods(RDF.add!)
# 4 methods for generic function "add!":
add!(graph::Graph,subject::URI,predicate::URI,object::Number) at /Users/jbaran/src/RDF/src/RDF.jl:29
add!(graph::Graph,subject::URI,predicate::URI,object::String) at /Users/jbaran/src/RDF/src/RDF.jl:36
add!(graph::Graph,subject::URI,predicate::URI,object::URI) at /Users/jbaran/src/RDF/src/RDF.jl:43
add!(graph::Graph,statement::Statement) at /Users/jbaran/src/RDF/src/RDF.jl:68
起初我以为是我使用了 object::Union(...),但即使我用 Number、String 和 URI 定义了三个函数,我也得到了这个错误.
At first I thought it was my use of object::Union(...), but even when I define three functions with Number, String, and URI, I get this error.
我有什么明显的遗漏吗?顺便说一句,我正在使用 Julia 0.2.1 x86_64-apple-darwin12.5.0.
Is there something obvious that I am missing? I am using Julia 0.2.1 x86_64-apple-darwin12.5.0, by the way.
谢谢,
金
推荐答案
您可能会被方法 extension 和函数 shadowing 之间的细微差别所困扰.
This looks like you may be getting bit by the very slight difference between method extension and function shadowing.
这是它的短处.当你写 function add!(::Graph, ...);……;end;
,Julia 查看 just 您的本地范围并查看是否定义了 add!
.如果是,那么它将使用这个新方法签名扩展该功能.但如果它尚未在本地定义,那么 Julia 会为该函数创建一个新的局部变量 add!
.
Here's the short of it. When you write function add!(::Graph, ...); …; end;
, Julia looks at just your local scope and sees if add!
is defined. If it is, then it will extend that function with this new method signature. But if it's not already defined locally, then Julia creates a new local variable add!
for that function.
正如 JMW 的评论所暗示的,我敢打赌,您有 两个 独立的 add!
函数.Base.add!
和 RDF.add!
.在您的 RDF 模块中,您将隐藏 Base.add!
的定义.这类似于您如何命名局部变量 pi = 3
而不会影响其他范围内的真实 Base.pi
.但在这种情况下,您希望将您的方法与 Base.add!
函数合并,并让多个调度负责解决问题.
As JMW's comment suggests, I bet that you have two independent add!
functions. Base.add!
and RDF.add!
. In your RDF module, you're shadowing the definition of Base.add!
. This is similar to how you can name a local variable pi = 3
without affecting the real Base.pi
in other scopes. But in this case, you want to merge your methods with the Base.add!
function and let multiple dispatch take care of the resolution.
方法扩展行为有两种获取方式:
There are two ways to get the method extension behavior:
在你的
module RDF
范围内,说import Base: add!
.这明确地将Base.add!
作为add!
带入您的本地范围,从而允许方法扩展.
Within your
module RDF
scope, sayimport Base: add!
. This explicitly bringsBase.add!
into your local scope asadd!
, allowing method extension.
将您的方法显式定义为 function Base.add!(graph::Graph, ...)
.我喜欢这种形式,因为它更明确地记录了您在定义站点扩展 Base
函数的意图.
Explicitly define your methods as function Base.add!(graph::Graph, …)
. I like this form as it more explicitly documents your intentions to extend the Base
function at the definition site.
这绝对可以得到更好的记录.Modules 部分对此有一个简短的参考,目前有
This could definitely be better documented. There's a short reference to this in the Modules section, and there's currently a pull request that should be merged soon that will help.
这篇关于尽管使用方法(...)显示,但未找到函数签名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!