如何在 LaTeX3 中创建本地标记列表变量?

如何在 LaTeX3 中创建本地标记列表变量?

这些\tl_new:(Nc)函数全局创建一个新的标记列表变量。有没有办法在本地创建一个新的标记列表变量?

答案1

“是也不是”。如果你坚持使用官方的编程方法,那么答案是“否”,因为团队决定的方法是所有变量都应该是已声明全局。另一方面,如果你决定“自己动手”,那么你可以这样做

\cs_set_nopar:Npn \l_my_tl { }

因为最终令牌列表是一个没有参数的宏(至少在当前实现中)。与变量不同,没有使用\cs_set_nopar:Npn或类似方法检查预先存在性。请注意,我是不是鼓励这样做,但你可以做到。(我们内部有几个地方需要这样做,最明显的是在定义操作tl本身时!)

(请注意,\tl_set:Nn \foo未声明的\foo将在本地创建它除非检查处于活动状态。可用的检查之一就是准确选择这种不受支持的行为。)

采用这种方法的原因是经验表明这是处理 TeX 中变量的最佳方法。TeX 中的变量按组(原始变量\begingroup/ \endgroup{/ }、 _ 等)确定范围,而不是按(宏)定义中的位置确定范围。团队尝试了本地创建变量,不仅tl是其他类型。这在技术上是可以实现的,但与 TeX 的底层范围不太吻合:可以理解为

\cs_new_protected:Npn \foo:
  {
    \<var>_local_new:N \l_my_<var>
    % Code
  }

是定义中的局部变量,而不是组中的局部变量。当发现这种方法没有特别大的帮助时,就放弃了局部初始化,从而导致目前的情况,即所有变量都应该全局声明,即使是在本地分配的。

(基于寄存器的变量比使用宏的变量更“稀缺”,因此几乎不需要担心tl或类似问题:本地提供的“节省”创建变量最适用于例如intdim类型。请注意,基于寄存器的变量名也必须声明,而基于宏的变量名则不必声明。但是,团队的一个目标是使用者expl3不应该依赖实现细节:我们保留在 API 保持不变的情况下更改内部创建变量的方式的权利。)

相关内容