课程表

Julia课程

工具箱
速查手册

Julia 模块

当前位置:免费教程 » 程序设计 » Julia

Julia 的模块是一个独立的全局变量工作区。它由句法限制在 module Name ... end 之间。在模块内部,你可以控制其他模块的命名是否可见(通过 import ),也可以指明本模块的命名是否为 public(通过 export)。

下面的例子展示了模块的主要特征。这个例子仅为演示:

  1. module MyModule
  2. using Lib
  3. using BigLib: thing1, thing2
  4. import Base.show
  5. importall OtherLib
  6. export MyType, foo
  7. type MyType
  8. x
  9. end
  10. bar(x) = 2x
  11. foo(a::MyType) = bar(a.x) + 1
  12. show(io, a::MyType) = print(io, "MyType $(a.x)")
  13. end

注意上述例子没有缩进模块体的代码,因为整体缩进没有必要。

这个模块定义了类型 MyType 和两个函数。foo 函数和 MyType 类型被 export ,因此可以被 import 进其他模块使用。 barMyModule 的私有函数。

语句 using Lib 表明,Lib 模块在需要时可用来解析命名。若一个全局变量在当前模块中没有被定义,系统会在 Lib export 的变量中搜索,并在找到后把它 import 进来。在当前模块中凡是用到这个全局变量时,都会去找 Lib 中变量的定义。

语句 using BigLib: thing1, thing2using BigLib.thing1, BigLib.thing2 的缩写。

import 关键字支持与 using 所有相同的语法,但只能在一个时间上对一个名称进行操作。它不像 using 那样会添加用于搜索的模块。importusing 的不同之处还在于导入这一功能时必须使用新的方法扩展后的 import

在上述的 MyModule 中我们想向标准的 show 功能增加一个方法,所以我们必须写下 import Base.show

那些函数名只有通过 using 功能才能看到的函数是不能被扩展的。

importall 关键字显式地导入导出指定模块的所有名称,其效果就像 import 单独使用在它们的所有名称一样。

一旦一个变量是通过 usingimport 使其可见的,一个模块就可能无法创建它自己的同名的变量了。输入变量必须是只读的;对全局变量赋值总是会影响当前模块所拥有的变量,否则就会引发错误。

模块使用方法的总结

我们要加载一个模块时,可以使用两个主要关键字:usingimport。要了解他们的差异,可以考虑下面的例子:

  1. module MyModule
  2. export x, y
  3. x() = "x"
  4. y() = "y"
  5. p() = "p"
  6. end

在这个模块中我们(使用关键字 export )导出 xy 功能,也包含了非导出函数 p 。我们有几个不同的方法来加载该模块及其内部功能到当前工作区,具体如下:

导入命令 导入变量 方法扩展可用项
using MyModule All export ed names (x and y), MyModule.x, MyModule.y and MyModule.p MyModule.x, MyModule.y and MyModule.p
using MyModule .x, MyModule.p x and p
using MyModule: x, p x and p
import MyModule MyModule.x, MyModule.y and MyModule.p MyModule.x, MyModule.y and MyModule.p
import MyModule.x, MyModule.p x and p x and p
import MyModule: x, p x and p x and p
importall MyModule All export ed names (x and y) x and y

模块和文件

大多数情况下,文件和文件名与模块无关;模块只与模块表达式有关。一个模块可以有多个文件,一个文件也可以有多个模块:

  1. module Foo
  2. include("file1.jl")
  3. include("file2.jl")
  4. end

在不同的模块中包含同样的代码,会带来类似 mixin 的特征。可以利用这点,在不同的环境定义下运行同样的代码,例如运行一些操作的“安全”版本来进行代码测试:

  1. module Normal
  2. include("mycode.jl")
  3. end
  4. module Testing
  5. include("safe_operators.jl")
  6. include("mycode.jl")
  7. end

标准模块

有三个重要的标准模块:Main, Core, 和 Base。

Main 是顶级模块,Julia 启动时将 Main 设为当前模块。提示符模式下,变量都是在 Main 模块中定义,whos() 可以列出 Main 中的所有变量。

Core 包含“内置”的所有标志符,例如部分核心语言,但不包括库。每个模块都隐含地调用了 using Core,因为没有这些声明,什么都做不了。

Base 是标准库( 在 base/ 文件夹下)。所有的模块都隐含地调用了 using Base,因为大部分情况下都需要它。

默认顶级声明和裸模块

除了 using Base,模块显式引入了所有的运算符。模块还自动包含 eval 函数的定义,这个函数对本模块中的表达式求值。

如果不想要这些定义,可以使用 baremodule 关键字来定义模块。使用 baremodule 时,一个标准的模块有如下格式:

  1. baremodule Mod
  2. using Base
  3. importall Base.Operators
  4. eval(x) = Core.eval(Mod, x)
  5. eval(m,x) = Core.eval(m, x)
  6. ...
  7. end

模块的相对和绝对路径

输入指令 using foo, Julia 会首先在 Main 名字空间中寻找 Foo。如果模块未找到, Julia 会尝试 require("Foo")。通常情况下, 这会从已安装的包中载入模块。

然而,有些模块还有子模块,也就是说,有时候不能从 Main 中直接引用一些模块。有两种方法可以解决这个问题:方法一,使用绝对路径,如 using Base.Sort。方法二,使用相对路径,这样可以方便地载入当前模块的子模块或者嵌套的模块:

  1. module Parent
  2. module Utils
  3. ...
  4. end
  5. using .Utils
  6. ...
  7. end

模块 Parent 包含子模块 Utils。如果想要 Utils 中的内容对 Parent 可见, 可以使用 using 加上英文句号。更多的句号表示在更下一层的命名空间进行搜索。例如,using ..Utils 将会在 Parent 模块的 子模块内寻找 Utils

模块文件路径

全局变量 LOAD_PATH 包含了调用 require 时 Julia搜索模块的目录。可以用 push! 进行扩展 :

  1. push!(LOAD_PATH, "/Path/To/My/Module/")

将这一段代码放在 ~\.juliarc.jl 里能够在每次 Julia启动时对 LOAD_PATH 扩展。此外,还可以通过定义环境变量 JULIA_LOAD_PATH 来扩展 Julia 的模块路径。

小提示

如果一个命名是有许可的(qualified)(如 Base.sin),即使它没被 export ,仍能被外部读取。这在调试时非常有用。

import 或 export 宏时,要在宏名字前添加 @ 符号,例如 import Mod.@mac 。在其他模块中的宏可以被调用为 Mod.@mac@Mod.mac

形如 M.x = y 的语法是错的,不能给另一个模块中的全局变量赋值;全局变量的赋值都是在变量所在的模块中进行的。

直接在顶层声明为 global x,可以将变量声明为“保留”的。这可以用来防止加载时,全局变量初始化遇到命名冲突。

转载本站内容时,请务必注明来自W3xue,违者必究。
 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号