为什么有一个函数可以(全局)定义一个标记列表\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 团队曾一度探索过局部范围内的变量声明:标记列表很容易,但诸如int
或dim
变量之类的东西则稍微复杂一些。(这是因为 TeX 寄存器用于后一种情况。)然而,在使用中很明显这并没有真正起作用:TeX 分组的基本原理意味着您总是需要一个\group_begin:
/\group_end:
对,而类似的东西\tl_new_local:N
可能会产生误导。
结果是,所有变量都在 中全局声明expl3
,但随后它们会根据需要用作始终本地或始终全局存储。 (混合本地和全局赋值可能会导致保存堆栈问题。)按照惯例,代码级别的变量名以 或 开头l
,g
以指示它们的用途。 类似地,大多数用于设置变量的函数都有“操作”部分以 开头的版本g
:这些是全局版本。 例如,我们有set
和gset
,put
和gput
,remove
和gremove
。 当变量被使用但未设置时,不存在拆分:例如,\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_tl
0 1 1