【问题标题】:Error occurred when loading a custom Julia module加载自定义 Julia 模块时出错
【发布时间】:2020-10-22 09:29:12
【问题描述】:

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

例如,我定义了一个名为myMoldulemodule 来包装一个可变结构Param 和一个函数addD:\\run\\defineModule.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

并在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(...) 中使用了绝对路径以避免使用LOAD_PATH 内容,并在模块名称前添加了.(即using .myMoldule)。

似乎是什么问题?

P.S.: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

【问题讨论】:

    标签: module julia


    【解决方案1】:

    待更正:

    • sumBase 中的一个函数,您应该使用不同的名称
    • 无需声明sum 变量(应命名为mysum
    • 删除::之前的空格
    • 模块名称应以大写字母开头
    • 您的模块名称有误,也许您加载的模块与您想象的不同?

    一旦更正你的代码就可以工作了。

    【讨论】:

    • 我修复了 Przemyslaw Szufel 指出的所有问题。我发现不是我命名sum 或模块的方式导致UndefVarError: Param not defined 错误。
    • 为读者澄清一点,:: 周围允许有空格,并且在定义structs 时可以很好地提高可读性。 :)
    【解决方案2】:

    出现问题是因为您使用的是.MyModule1,而不是MyModule2,因此您将Param 导入到主模块而不是MyModule2,因此Module2 看不到Param

    如果你将using ..MyModule1(两个点而不是一个,因为你还有一个级别)放入MyModule2,这个问题就会消失。

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

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

    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
    

    【讨论】:

      【解决方案3】:

      提问者说明:以下被否决的新问题(可能)是从原来的问题扩展而来的,Vitaliy Yakovchuk回答得很好。


      我修复了 Przemyslaw Szufel 指出的所有问题。在我上面的例子中,导致问题的不是不正确的命名方式。

      现在,我有一个更好的例子来澄清我的问题。

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

      1. "D:\\run\\defineModule1.jl":
      module MyModule1
      
          export Param
      
          mutable struct Param
              x::Int64
              y::Int64
          end
      
      end # end of module
      
      1. "D:\\run\\defineModule2.jl":
      include("D:\\run\\defineModule1.jl"); using .MyModule1
      
      module MyModule2
      
          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
      

      注意这里没有定义Param,为了使Param可用,添加一行include("D:\\run\\defineModule1.jl"); using .MyModule1作为该文件的第一行。

      1. "D:\\run\\useModule.jl":
      include("D:\\run\\defineModule1.jl"); using .MyModule1
      include("D:\\run\\defineModule2.jl"); 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 中的函数myAdd(param)mySubtract(param) 都需要defineModule1.jl 中的预定义可变结构Param

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

      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
      

      我认为,通过在“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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-02-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-21
        相关资源
        最近更新 更多