Module 加载自定义模块时出错

Module 加载自定义模块时出错,module,julia,Module,Julia,我一直对如何在Julia中定义和使用自定义模块感到困惑 例如,我在D:\\run\\defineModule.jl中定义了一个名为myMoldule的module模块来包装一个可变结构Param和一个函数add: module myMoldule export Param, add mutable struct Param x ::Int64 y ::Int64 end function add(x::Int64, y::In

我一直对如何在Julia中定义和使用自定义
模块感到困惑

例如,我在
D:\\run\\defineModule.jl
中定义了一个名为
myMoldule
module
模块来包装一个可变结构
Param
和一个函数
add

module myMoldule

    export Param, add

    mutable struct Param
        x ::Int64
        y ::Int64
    end

    function add(x::Int64, y::Int64)
        sum ::Int64
        sum = x + y
        return sum
    end
end
julia> include("D:\\run\\useModule.jl")
WARNING: replacing module MyModule1.
WARNING: replacing module MyModule1.
WARNING: replacing module MyModule2.
ERROR: LoadError: LoadError: UndefVarError: Param not defined
Stacktrace:
 [1] top-level scope at D:\run\defineModule2.jl:7
 [2] include(::String) at .\client.jl:457
 [3] top-level scope at D:\run\useModule.jl:2
 [4] include(::String) at .\client.jl:457
 [5] top-level scope at none:1
in expression starting at D:\run\defineModule2.jl:7
in expression starting at D:\run\useModule.jl:2
include("./defineModule1.jl")
include("./defineModule2.jl")
using .MyModule1
using .MyModule2

function testModule()

    param = Param(1, 2)

    # call myAdd to get the sum of param.x and param.y
    sumValue = myAdd(param)
    println(sumValue)

    # call mySubtract to get the difference of param.x and param.y
    difValue = mySubtract(param)
    println(difValue)
    
end

并在
D:\\run\\useModule.jl
中使用此模块,如:

include("D:\\run\\defineModule.jl")
using .myMoldule

function testModule()
    param = Param(1, 2)
    sum   = add(param.x, param.y)
    println(sum)
end
运行
testModule()
时出错,如下所示:

julia> testModule()
ERROR: UndefVarError: Param not defined
Stacktrace:
 [1] testModule() at D:\run\useModule.jl:8
 [2] top-level scope at none:1
请注意,我在
include(…)
中使用了绝对路径以避免使用
加载路径
东西,并在模块名称之前添加了
(即,
使用.myMoldule

有什么问题吗

备注:Julia版本信息:

julia> versioninfo()
Julia Version 1.5.2
Commit 539f3ce943 (2020-09-23 23:17 UTC)
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: Intel(R) Core(TM) i7-8700K CPU @ 3.70GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-9.0.1 (ORCJIT, skylake)
Environment:
  JULIA_DEPOT_PATH = C:\Users\f\.julia;C:\opt\JuliaPro-1.5.2-1\Julia-1.5.2\local\share\julia;C:\opt\JuliaPro-1.5.2-1\Julia-1.5.2\share\julia
  JULIA_LOAD_PATH = @;@v#.#;@stdlib
  JULIA_NUM_THREADS = 6
  JULIA_PKG_SERVER = pkg.juliahub.com

需要作出的更正:

  • sum
    Base
    中的一个函数,您应该使用不同的名称
  • 无需声明
    sum
    变量(它的名称应类似于
    mysum
  • 删除
    ::
  • 模块名称应以大写字母开头
  • 你在模块名称上有一个输入错误,也许你正在加载一个与你想象中不同的模块

一旦更正了代码,您的代码就可以正常工作。

发问者说明:以下被否决的新问题(可能)从原来的问题扩展而来,并由Vitaliy Yakovchuk很好地回答了



我解决了Przemyslaw Szufel指出的所有问题。在我上面的例子中,不是不恰当的命名方式导致了这个问题

现在,我有一个更好的exmaple来澄清我的问题

假设为了满足需要,我必须将julia源代码分为两个模块,例如,在
defineModule1.jl
中定义可变结构
Param
,在
defineModule2.jl
中定义函数。代码脚本如下所示:

julia> testModule()
ERROR: UndefVarError: Param not defined
Stacktrace:
 [1] testModule() at D:\run\useModule.jl:8
 [2] top-level scope at none:1
  • “D:\\run\\defineModule1.jl”
  • “D:\\run\\defineModule2.jl”
  • 请注意,此处未定义
    Param
    ,要使
    Param
    可用,请使用一行
    include(“D:\\run\\defineModule1.jl”);using.MyModule1
    作为此文件的第一行添加

  • “D:\\run\\useModule.jl”
  • 请注意,脚本
    defineModule2.jl
    中的函数
    myAdd(param)
    mySubtract(param)
    都需要
    defineModule1.jl
    中预定义的可变结构
    param

    这是我运行
    D:\\run\\useModule.jl时得到的:

    module myMoldule
    
        export Param, add
    
        mutable struct Param
            x ::Int64
            y ::Int64
        end
    
        function add(x::Int64, y::Int64)
            sum ::Int64
            sum = x + y
            return sum
        end
    end
    
    julia> include("D:\\run\\useModule.jl")
    WARNING: replacing module MyModule1.
    WARNING: replacing module MyModule1.
    WARNING: replacing module MyModule2.
    ERROR: LoadError: LoadError: UndefVarError: Param not defined
    Stacktrace:
     [1] top-level scope at D:\run\defineModule2.jl:7
     [2] include(::String) at .\client.jl:457
     [3] top-level scope at D:\run\useModule.jl:2
     [4] include(::String) at .\client.jl:457
     [5] top-level scope at none:1
    in expression starting at D:\run\defineModule2.jl:7
    in expression starting at D:\run\useModule.jl:2
    
    include("./defineModule1.jl")
    include("./defineModule2.jl")
    using .MyModule1
    using .MyModule2
    
    function testModule()
    
        param = Param(1, 2)
    
        # call myAdd to get the sum of param.x and param.y
        sumValue = myAdd(param)
        println(sumValue)
    
        # call mySubtract to get the difference of param.x and param.y
        difValue = mySubtract(param)
        println(difValue)
        
    end
    
    
    我认为,通过在“D:\run\useModule.jl”开头使用以下行,应该可以找到可变结构
    Param

    include("D:\\run\\defineModule1.jl"); using .MyModule1
    include("D:\\run\\defineModule2.jl"); using .MyModule2
    ...
    
    仍然会报告错误
    LoadError:UndefVarError:Param not defined


    那么,为什么
    D:\\run\\useModule.jl
    找不到
    Param

    问题的发生是因为您正在使用
    .MyModule1
    ,而不是在
    MyModule2
    中,因此您将
    Param
    导入主模块,而不是
    MyModule2
    ,因此Module2看不到
    Param

    如果您将使用..MyModule1
    放入
    MyModule2
    中(两个点而不是一个点,因为您还有一个级别),则此问题将继续

    但是,您的代码仍然无法工作,因为julia的
    include
    函数只运行包含文件的所有内容,因此即使包含同一个文件,也会创建不同的模块实例。此警告
    警告:替换模块…
    表示您可能在代码中的某个地方使用不同版本的模块(在您的情况下,是Main.Module1和Main.Module2.Module1)

    julia中的常见做法是在一个位置包含所有文件(它们只应包含一次)。例如,您可以将所有包含项放入文件
    useModule.jl

    module myMoldule
    
        export Param, add
    
        mutable struct Param
            x ::Int64
            y ::Int64
        end
    
        function add(x::Int64, y::Int64)
            sum ::Int64
            sum = x + y
            return sum
        end
    end
    
    julia> include("D:\\run\\useModule.jl")
    WARNING: replacing module MyModule1.
    WARNING: replacing module MyModule1.
    WARNING: replacing module MyModule2.
    ERROR: LoadError: LoadError: UndefVarError: Param not defined
    Stacktrace:
     [1] top-level scope at D:\run\defineModule2.jl:7
     [2] include(::String) at .\client.jl:457
     [3] top-level scope at D:\run\useModule.jl:2
     [4] include(::String) at .\client.jl:457
     [5] top-level scope at none:1
    in expression starting at D:\run\defineModule2.jl:7
    in expression starting at D:\run\useModule.jl:2
    
    include("./defineModule1.jl")
    include("./defineModule2.jl")
    using .MyModule1
    using .MyModule2
    
    function testModule()
    
        param = Param(1, 2)
    
        # call myAdd to get the sum of param.x and param.y
        sumValue = myAdd(param)
        println(sumValue)
    
        # call mySubtract to get the difference of param.x and param.y
        difValue = mySubtract(param)
        println(difValue)
        
    end
    
    
    不要在其他地方包含文件。例如
    defineModule2.jl
    内容:

    
    module MyModule2
    
        using ..MyModule1
    
        export myAdd, mySubtract
    
        function myAdd(param::Param)
            return param.x + param.y
        end
    
        function mySubtract(param::Param)
            return param.x - param.y
        end
    
    end # end of module
    

    我解决了Przemyslaw Szufel指出的所有问题。我发现并不是我命名的
    sum
    或module导致了
    UndefVarError:Param not defined
    错误。读者需要注意的是,在
    ::
    周围允许空格,并且在定义
    结构时,空格对于可读性很好