现在位置: 首页 > Julia 教程 > 正文

Julia 模块与包管理

模块(module)用于把代码组织成独立的命名空间,避免命名冲突;包(package)则是打包发布的模块,通过内置的包管理器 Pkg 安装。


定义模块

使用 module ... end 定义模块:

实例

module MyModule

# export 声明对外公开的名字(可以写在模块任意位置)
export myfunc, PI

const PI = 3.14159

myfunc(x) = x * 2

# 没有导出的名字属于模块私有
helper(x) = x + 1

end

访问模块成员的三种方式

实例

# 方式一:通过模块名限定访问(总是可用)
julia> MyModule.PI
3.14159

julia> MyModule.myfunc(10)
20

# 方式二:using 导入模块名和所有 export 的名字
julia> using .MyModule

julia> myfunc(10)     # 导出的名字可以直接用
20

julia> helper(10)     # 未导出的名字不能用,需要 MyModule.helper
ERROR: UndefVarError: `helper` not defined in `Main`

# 方式三:import 只导入模块名本身
julia> import .MyModule

julia> MyModule.myfunc(1)
2

usingimport 的区别总结:

语句效果能否无限定扩展方法
using M导入模块名 + 全部导出名字不能(需要写 M.f)
import M只导入模块名不能
import M: f只导入名字 f可以,直接写 f 新方法
using M: f只导入名字 f不能

注意:上面的例子中 using .MyModule 里的点表示"当前作用域中定义的模块"。从 REPL 或脚本中加载本地模块必须加点前缀;从已安装的包加载则直接写包名,如 using Example

include 与多文件模块

实际项目中,模块代码通常拆分到多个文件,用 include() 组装:

实例

module MyPkg

include("types.jl")     # 把文件内容在当前模块中执行
include("functions.jl")

end

标准模块

模块说明
Main顶层模块,REPL 和脚本默认运行在 Main 中
Base基础库,默认自动可用(sum、push! 等都在这里)
Core语言内置功能,编译器相关
标准库模块随 Julia 附带、无需安装,如 Dates、Test、LinearAlgebra 等,需要 using 后使用

包管理器 Pkg

Julia 自带包管理器 Pkg,可以在 REPL 的 Pkg 模式中使用(输入 ] 进入),也可以通过 using Pkg 在代码中调用。

Pkg 模式常用命令

命令功能
add 包名安装包
rm 包名卸载包
update 包名更新包(无参数更新全部)
status查看当前环境安装了哪些包
activate 路径激活(切换)当前环境
test 包名运行包的测试
precompile预编译所有依赖

实例:安装并使用第三方包

# 1. 按 ] 进入 Pkg 模式,安装 Example 包
(@v1.10) pkg> add Example

# 2. 按退格键回到 Julia 模式,加载并使用
julia> using Example

julia> hello("RUNOOB")
"Hello, RUNOOB"

代码中等价的写法:

实例

using Pkg

Pkg.add("Example")      # 安装包

Pkg.status()            # 查看已安装的包

使用标准库

标准库随 Julia 一起安装,直接 using 即可,不需要 add:

实例

julia> using LinearAlgebra

julia> I             # 单位矩阵记号
UniformScaling{Bool}(true)

julia> [1 2; 3 4] * I
2×2 Matrix{Int64}:
 1  2
 3  4

环境(Environment)

Julia 的包安装在环境中。每个环境由一个项目目录描述,包含两个文件:

文件作用
Project.toml项目的直接依赖列表和兼容性约束,应提交到版本库
Manifest.toml完整的依赖图快照(包括间接依赖的精确版本),保证环境可复现

创建并使用项目环境

实例

# 1. 在终端创建项目目录
$ mkdir myproject && cd myproject

# 2. 启动 Julia,激活当前目录为环境
$ julia

julia> using Pkg

julia> Pkg.activate(".")
  Activating project at `~/myproject`

# 3. 安装依赖,会生成 Project.toml 和 Manifest.toml
julia> Pkg.add("JSON")

# 4. 以后只要在这个目录下启动 Julia,就自动使用这个环境

最佳实践:不要把所有包装进默认环境(@v1.10),而是为每个项目建独立环境。这样不同项目可以使用同一个包的不同版本,互不干扰,还能通过提交 Project.toml 让别人精确复现你的环境。


开发自己的包

用 Pkg 可以快速生成一个包的骨架:

julia> ] generate MyPkg
Generating  project MyPkg:
    MyPkg/Project.toml
    MyPkg/src/MyPkg.jl

生成的包主文件结构如下:

MyPkg/src/MyPkg.jl 文件

module MyPkg

# export 列出对外提供的函数
export greet

# 一个示例函数
greet() = "Hello from MyPkg!"

end

在包目录下启动 Julia 并激活环境后,就可以直接 using 自己的包:

julia> ] activate MyPkg
julia> using MyPkg

julia> greet()
"Hello from MyPkg!"

扩展 Base 函数时的 import 写法

在自己包里给 Base 的函数添加新方法时,建议用 import 明确声明:

实例

module MyPkg

import Base: show     # import 后才能给 show 添加新方法

struct Temp
    celsius::Float64
end

# 为自定义类型扩展 Base.show
function Base.show(io::IO, t::Temp)
    print(io, "$(t.celsius)°C")
end

end