`\tl_new:N` 标记列表中的 `put` 和 `gput` 有什么区别?

`\tl_new:N` 标记列表中的 `put` 和 `gput` 有什么区别?

为什么有一个函数可以(全局)定义一个标记列表\tl_new:N,但有两个函数可以将元素放入其中:\tl_put_left:Nn\tl_gput_left:nN

g开头的这个是什么gput意思?“全球”?

如何将本地项目放入全局列表(或反之亦然)?

现在,在写这个问题的时候:我可以使用“本地”修改来对当前分组中不存在的列表修改进行修改吗?

答案1

我看到Phelype 已经介绍了关键点:在这里我将尝试提供一些该方法的背景。

要理解这里的想法,最好先了解一下 TeX 分组的工作原理。作为宏扩展语言,TeX 没有“在”宏中的概念,因此定义不会形成范围。相反,范围是由例如原语\begingroup/明确创建的\endgroup,在 中expl3称为\group_begin:\group_end:

这也意味着局部变量的工作方式与其他一些语言不同。例如,

\begingroup
  \def\foo{abc}
  \begingroup
  \show\foo

或者expl3

\group_begin:
  \tl_set:Nn \foo { abc }
  \group_begin:
  \tl_show:N \foo

我们看到它的\foo定义并扩展为abc:嵌套组从其父级“继承”所有局部变量。

这很重要,因为它会影响 TeX 本身上的抽象是否有意义。LaTeX 团队曾一度探索过局部范围内的变量声明:标记列表很容易,但诸如intdim变量之类的东西则稍微复杂一些。(这是因为 TeX 寄存器用于后一种情况。)然而,在使用中很明显这并没有真正起作用:TeX 分组的基本原理意味着您总是需要一个\group_begin:/\group_end:对,而类似的东西\tl_new_local:N可能会产生误导。

结果是,所有变量都在 中全局声明expl3,但随后它们会根据需要用作始终本地或始终全局存储。 (混合本地和全局赋值可能会导致保存堆栈问题。)按照惯例,代码级别的变量名以 或 开头lg以指示它们的用途。 类似地,大多数用于设置变量的函数都有“操作”部分以 开头的版本g:这些是全局版本。 例如,我们有setgsetputgputremovegremove。 当变量被使用但未设置时,不存在拆分:例如,\tl_use:N可以应用于本地和全局标记列表。

最终结果是,应该声明一个变量一次,注意其名称中的预期范围,然后使用匹配的“设置”函数。

\tl_new:N \l_my_tl
\tl_new:N \g_my_tl
\group_begin:
  \tl_set:Nn \l_my_tl { a }
  \tl_gset::Nn \g_my_tl { b }
  % ...
\group_end:
% \l_my_tl back to empty, \g_my_tl still 'b'

答案2

为什么有一个函数可以(全局)定义一个标记列表\tl_new:N,但有两个函数可以将元素放入其中:\tl_put_left:Nn\tl_gput_left:nN

因为所有变量都应该全局声明一次,然后根据需要使用。在某个范围内声明后就不存在的变量几乎没有用处。这样的变量是临时变量,因此可以全局创建(\tl_new:N \l_my_temp_tl例如),然后在本地用于临时存储。事实上,LaTeX2e 的变量(计数器、长度、跳过、IO 流等)也都是全局定义的。

有两个用于赋值的函数,因为与变量声明不同,它的使用可能需要是全局的或局部的,这就是为什么有两个命令。全局变量(其名称以\g_...)应该总是使用函数的全局变体,使用局部变体也是如此。这是因为混合使用它们是不好的做法,可能会导致 TeX 耗尽其保存的堆栈内存。

g开头的这个是什么gput意思?“全球”?

是的 :-)

请参阅章节3.2.3 变量:作用域和类型expl3和 LaTeX 编程texdoc expl3)。

如何将本地项目放入全局列表(或反之亦然)?

你不能。你实际上可以,但你绝对不应该!

现在,在写这个问题的时候:我可以使用“本地”修改来对当前分组中不存在的列表修改进行修改吗?

是的。TeX 的作用域模型与 中的相同expl3。例如:

\documentclass{article}
\usepackage{expl3}
\begin{document}
\ExplSyntaxOn
\tl_new:N \l_my_global_tl
\tl_set:Nn \l_my_global_tl { 0~ }
\tl_use:N \l_my_global_tl
\group_begin:
  \tl_set:Nn \l_my_global_tl { 1~ }
  \tl_use:N \l_my_global_tl
\group_end:
\tl_use:N \l_my_global_tl
\ExplSyntaxOff
\end{document}

打印0 1 0,而相同的文档,\tl_set:Nn通过\tl_gset:Nn和打印\l_my_global_tl来替换。\g_my_global_tl0 1 1

相关内容