Skip to content
Zheng Junjie edited this page Mar 23, 2024 · 4 revisions

此篇简单介绍一下 guile 中的 module

尚未完工

最基础定义一个模块就是使用 define-module , 第二个括号就是模块名,一般与文件名相对应,例如 (guix channels) 模块位于 guix/channels.scm

(define-module (module-name))

使用模块

(use-modules (guix))

define-module 有各种参数

#:use-module

(define-module (module-name)
  #:use-module (other-module))

定义本文件的模块名为 module-name, 并使用了 other-module 模块, 相当于

(define-module (module-name))
(use-modules (other-module))

#:select

#:use-module 中可以使用 #:select 选择性的导入模块中的内容

(define-module (other-module)
  #:export (a-procedure))
(define (a-procedure) (pk 'hello!))
(define-module (module-name)
  #:use-module ((other-module) #:select (a-procedure)))
(a-procedure)

也可改名

(define-module (module-name)
  #:use-module ((other-module) #:select ((a-procedure . b-procedure))))
(b-procedure)

#:hide

有时候有几个过程不想要导入

(use-modules ((gnu packages) #:hide (specification->package))
(specification->package "hello")

就找不到 specification->package

#:prefix

给导入的内容增加前缀,例如

(use-modules ((guix licenses) #:prefix license:))
(pk license:gpl2+)

这样就可以避免某些命名冲突或者更好看。

#:renamer

#:autoload

有时候我们并不需要每次导入模块,例如只在一个 procedure 中要使用,或是两个模块相互依赖,就可以使用 #:autoload

(define-module (module-name)
  #:autoload (other-module) (a-procedure))

这样当在执行 a-procedure,时就会尝试加载 (other-module)

#:export

导出 (export a-procedure)

(define-module (module-name)
  #:export (a-procedure))
(define a-procedure pk)

(define-module (module-name))
(define a-procedure pk)
(export a-procedure)
(define-module (module-name))
(define-public a-procedure pk)

其他一些 procedure 及 syntax

resolve-interface

查找一个模块,带有修改

save-module-excursion

有时候像要从其他文件加载代码,但不想被修改当前模块,就使用 save-module-excursion 进行包裹

(define-module (module-name))
(save-module-excursion
 (lambda ()
   (primitive-load "a-file")))

@

(@ (gnu packages) specification->package) 直接使用 (gnu packages) 中的 specification->package 函数,它必须已经导出

@@

类似 @,但是可以强制使用内部内容

reload-module

重新加载模块

define-once

当重新加载模块,但不想其中部分被重新定义,例如数据由其中一个变量保存着 就使用 defien-once