gpt4 book ai didi

racket - Racket 中的 -D 选项和#ifdef

转载 作者:行者123 更新时间:2023-12-05 03:10:00 31 4
gpt4 key购买 nike

在 C 中,您可以使用选项编译,例如 -DPROMPT。然后,在文件中你可以有 #ifdef PROMPT 并且代码将在编译时转换以包含该 block 中的内容。

Racket 中有类似的东西吗?我尝试了 racket --help 但没有看到任何有用的选项。

最佳答案

是的,但它的工作方式与在 C 中的工作方式略有不同。正如 Alexis 所说,Racket 编译是半不可见的。然而,在 Racket 回声系统中有一些工具可以做到这一点,最流行的是 errortrace。 .

任何时候你使用 define-syntax ,如果愿意,您正在编写一个编译器插件。这和 C 之间的主要区别在于,在 C 中,您需要在称为预处理器指令的半生不熟的 DSL 中编写这些扩展,而在 Racket 中,您可以使用 Racket 的全部功能编写这些扩展.

这意味着你在 Racket 中用来与外界交流的任何结构,你也可以在这里使用。一个例子,正如 Jens 所建议的那样,是使用环境变量。但是由于您明确要求能够传递参数,因此您可以使用 current-command-line-arguments ,或者更好的是,command-line模块,为您解析命令行参数。

作为其工作原理的示例,以下文件将编译为显示符号 'build'no-build,具体取决于是否有任何参数通过命令行传递:

#lang racket

(require (for-syntax syntax/parse
racket/cmdline))

(define-syntax (arguments? stx)
(syntax-parse stx
[(_)
(if (null?
(command-line
#:args args
args))
#''no-build
#''build)]))

(arguments?)

这与仅使用 if 而没有 define-syntax 的不同之处在于,在第一种情况下,这发生在编译 时,而不是 运行时间,可以这么说。

当您使用 raco make 命令在不同于运行代码的时间编译代码时,这一点最为明显。

首先,让我们尝试同时运行和编译:

$ racket example.rkt
'no-build
$ racket example.rkt an-argument
'build

但是,现在让我们尝试在运行之前编译它,使用 raco make:

$ raco make example.rkt
$ racket example.rkt
'build

看到这里,即使我们没有将任何参数传递给 example.rkt,它仍然返回 'build。这是因为选择完全是在编译时做出的,当 raco make 运行时。对 raco make 的调用确实有 1 个参数:文件 example.rkt,因此,它被编译后仅显示 'build

这个操作可以通过删除编译后的文件来撤销:

$ rm compiled/example_rkt.*

并重新运行示例:

$ racket example.rkt
'no-build

事实上,您甚至可以在编译后删除 example.rkt 文件:

$ raco make example.rkt
$ rm example.rkt
$ racket example.rkt
'build

尽管通常不要这样做,因为除非您在某处备份了您的源代码,否则您将无法再检索它。

最后,如果您想使用与在 C 中使用的完全相同的 -D 语法,command-line有一个 #:multi 选项,您可以使用它来设置您希望代码编译的方式。

不过,正如最后一点,请注意编译 racket 文件与编译 C 文件的不同之处在于生成的 zo 文件是 transient 的。它们只能在当前版本的 Racket VM 上工作,并且由于它经常更新(一年几次),你最好分发源代码。如果您想以类似于分发 C 二进制文件的方式对其进行混淆,您也可以分发完全扩展的代码,但这是对不同问题的回答。

关于racket - Racket 中的 -D 选项和#ifdef,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41414895/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com