在 Julia 中包含一个模块并从另一个模块中调用其函数之一
Including a module and calling one of its functions from within another module in Julia
假设我有一个模块 Module1,它定义了一个结构和一个 fit() 函数。我有另一个模块,称为 Parent,它包括 Module1 并定义了一个也调用 fit() 的 test() 函数。如果我从模块 1 定义结构,然后从 Parent 调用 test(),我就会遇到名称空间问题。这是此示例的代码:
#this module would be in a separate file
module Module1
struct StructMod1
end
export StructMod1
function fit(s::StructMod1)
end
export fit
end
module Parent
#including the module with include("Module1.jl")
module Module1
struct StructMod1
end
export StructMod1
function fit(s::StructMod1)
end
export fit
end
#including the exports from the module
using .Module1
function test(s::StructMod1)
fit(s)
return s
end
export test
end
using .Parent, .Module1
s = Parent.Module1.StructMod1()
@show test(s)
s2 = StructMod1()
@show test(s2)
和输出
test(s) = Main.Parent.Module1.StructMod1()
ERROR: LoadError: MethodError: no method matching test(::StructMod1)
Closest candidates are:
test(::Main.Parent.Module1.StructMod1)
或者,如果我将 using .Module1 替换为 using ..Module1,则 s2 的定义有效。但是,当使用 .Parent 调用时,我必须确保已经加载了 Module1。
用一个模块定义结构然后将其与另一个模块的函数一起使用的最佳方法是什么?
双重包含导致错误。在您的示例中,Parent.Module1
与 Module1
不同。将 include
视为愚蠢的 copy/paste 很有用。即使它们共享相同的源文件,双重包含也会使它们显示为两个不同的模块(如您的示例所示)。
解决方法是只include
一次,用relative imports引用模块
至于组织整个模块集,我喜欢 include
在主模块中按顺序排列所有模块,然后在需要的地方使用相对导入。我发现这是最简单的方法。
最终版本看起来像这样:
# Module1.jl
module Module1
struct StructMod1
end
export StructMod1
function fit(s::StructMod1)
end
export fit
end
# Parent.jl
module Parent
using ..Module1
function test(s::StructMod1)
fit(s)
return s
end
export test
end
#Main.jl
include("Module1.jl")
include("Parent.jl")
using .Parent, .Module1
s = Parent.Module1.StructMod1()
@show test(s)
s2 = StructMod1()
@show test(s2)
假设我有一个模块 Module1,它定义了一个结构和一个 fit() 函数。我有另一个模块,称为 Parent,它包括 Module1 并定义了一个也调用 fit() 的 test() 函数。如果我从模块 1 定义结构,然后从 Parent 调用 test(),我就会遇到名称空间问题。这是此示例的代码:
#this module would be in a separate file
module Module1
struct StructMod1
end
export StructMod1
function fit(s::StructMod1)
end
export fit
end
module Parent
#including the module with include("Module1.jl")
module Module1
struct StructMod1
end
export StructMod1
function fit(s::StructMod1)
end
export fit
end
#including the exports from the module
using .Module1
function test(s::StructMod1)
fit(s)
return s
end
export test
end
using .Parent, .Module1
s = Parent.Module1.StructMod1()
@show test(s)
s2 = StructMod1()
@show test(s2)
和输出
test(s) = Main.Parent.Module1.StructMod1()
ERROR: LoadError: MethodError: no method matching test(::StructMod1)
Closest candidates are:
test(::Main.Parent.Module1.StructMod1)
或者,如果我将 using .Module1 替换为 using ..Module1,则 s2 的定义有效。但是,当使用 .Parent 调用时,我必须确保已经加载了 Module1。
用一个模块定义结构然后将其与另一个模块的函数一起使用的最佳方法是什么?
双重包含导致错误。在您的示例中,Parent.Module1
与 Module1
不同。将 include
视为愚蠢的 copy/paste 很有用。即使它们共享相同的源文件,双重包含也会使它们显示为两个不同的模块(如您的示例所示)。
解决方法是只include
一次,用relative imports引用模块
至于组织整个模块集,我喜欢 include
在主模块中按顺序排列所有模块,然后在需要的地方使用相对导入。我发现这是最简单的方法。
最终版本看起来像这样:
# Module1.jl
module Module1
struct StructMod1
end
export StructMod1
function fit(s::StructMod1)
end
export fit
end
# Parent.jl
module Parent
using ..Module1
function test(s::StructMod1)
fit(s)
return s
end
export test
end
#Main.jl
include("Module1.jl")
include("Parent.jl")
using .Parent, .Module1
s = Parent.Module1.StructMod1()
@show test(s)
s2 = StructMod1()
@show test(s2)