假设我在一个 txt 文件中有一个外部数据结构的集合。 每当我需要数据进行计算时,我都必须解析文件,然后使用它的值。 如何更方便?
write
将其写入SCM文件中。然后可以使用 read
轻松阅读完整列表。当然可以,但是...(每次都必须读取数据的复杂列表表示,并且之后必须形成所有记录 - 如果数据已经编译,则可以避免这种情况)一个简化的例子:
让复杂数据只是外部文件中的单个数字DATA.txt:
10
让我们创建一个模块 data.scm 来读取外部数据,存储并导出它:
(define-module (data))
(export DATA)
(define DATA (with-input-from-file "DATA.txt" read))
让我们用 test.scm 来测试这种方法:
(add-to-load-path (dirname (current-filename)))
(use-modules (data))
(format #t "DATA: ~a\n" DATA)
这似乎有效(自动编译已打开,甚至使用了
guild compile data.scm
):
$ guile test.scm
DATA: 10
但是,当我删除 DATA.txt 文件时,会出现错误,因为(已编译的)data 模块缺少用于读取的 DATA.txt 文件!
那么问题来了:实际上如何在编译时将外部数据存储在模块中?
什么有效 - 但很丑!
要按字面意思生成模块文件,例如:
(define DATA (with-input-from-file "DATA.txt" read))
(with-output-to-file "data.scm"
(lambda ()
(format #t
"(define-module (data))
(export DATA)
(define DATA ~a)\n"
DATA)))
这种方法就像使用 C 宏,但没有利用该方案的宏(即语法)。 真的没有优雅的方案方式吗?
data.scm模块文件可以编码如下:
(define-module (data))
(export DATA)
(define-macro (define-get name file)
`(define ,name
,(with-input-from-file file read)))
(define-get DATA "DATA.txt")
这是一种解决方案。还是不能用syntax-case正确写出来,这会让我更开心。仍然不明白为什么原来的
(define DATA ...)
不起作用,正如我一直认为在scheme中,参数在使用之前首先被评估。