![解释3:何时将变量定义为 \l_... 或 \g_... 类型变量?](https://linux22.com/image/474402/%E8%A7%A3%E9%87%8A3%EF%BC%9A%E4%BD%95%E6%97%B6%E5%B0%86%E5%8F%98%E9%87%8F%E5%AE%9A%E4%B9%89%E4%B8%BA%20%5Cl_...%20%E6%88%96%20%5Cg_...%20%E7%B1%BB%E5%9E%8B%E5%8F%98%E9%87%8F%EF%BC%9F.png)
变量是否应为 a\g_
或l_
类型变量,程序员是否可以或多或少自由地决定?或者程序包创建者是否应遵守一些严格的规则或至少一些最佳实践?
我觉得有时判断一个变量是“全局的”还是“局部的”有点棘手,但这也可能是因为我不完全理解为什么在 TeX 中区分它如此重要。这个很好的答案这表明它与 TeX 内部的工作方式有关,并且 LaTeX3 手册指出g_
类型变量应该总是可以使用各种类型g
操作(例如gset
)进行全局设置。还有此问答,但它更关注\c_
和g_
类型变量的区别。
我通常会在“根”级别定义变量(因此是“全局”的,因为我可以在任何范围内使用它们)。但如果我想在函数内部设置和使用这样的变量,并且其值应该在此函数内,我会认为这个变量应该是l_
类型变量。这可能很容易决定。但什么时候变量应该是g_
类型变量?
我认为由文档选项键设置的布尔变量可能是g_
类型变量的候选。但话又说回来,包中可能定义了一些命令,允许在文档中间甚至在范围内将这些变量设置为不同的值,在这种情况下,我可能仍然应该选择l_
类型变量。所以,我认为这真的取决于变量在包中的使用方式。
也许我可以遵守以下规则(为了完整性,我还在c_
这里添加了类型):
- 变量是否应该改变?如果否:使用类型
\c_
。如果是: - 在包的上下文中,变量是否合理仅有的通过类型操作设置
g
?如果是:请使用g_
类型。 - 在所有其他情况下:使用
l_
类型。
这是一个明智的做法吗?有没有关于如何决定是否使用g_
或 的最佳实践l_
?
答案1
编程的一般规则是使用局部变量,除非另有需要。TeX 的作用域规则意味着这与其他语言不太一样,但总体思路是一致的。
\begingroup
在 TeX 中,范围由组( /\endgroup
或{
/ }
)以及一些“固有分组”构造(\halign
单元格、数学模式等)定义。在此类组之前本地设置的值可用的组内,但如果改变重置在组的末尾。使用expl3
不能改变这些基本规则,只能帮助我们跟踪它们。
因此,大多数时候你都想使用\l_...
变量。虽然expl3
在全局范围内定义名称(因为 TeX 没有内置命名空间),但它们只能在本地设置。因此,例如我们可能有
\tl_new:N \l_my_first_tl
\tl_set:Nn \l_my_first_tl { a }
\group_begin:
\tl_show:N \l_my_first_tl % => a
\tl_set:Nn \l_my_first_tl { b }
\tl_show:N \l_my_first_tl % => b
\group_end:
\tl_show:N \l_my_first_tl % => a
当您知道设置需要将组转义到全局上下文时,应谨慎使用全局变量:通常是文档范围内的内容,但也用于需要转义任意组级别的想法。这有时会导致使用本地和全局变量对,以便在文档中的给定点,可以保存和恢复本地版本。
碰巧在顶层设置的东西不一定是全局的:只有当你需要的时候放组内并具有价值逃逸。
\l_...
仅在调试处于活动状态时才强制使用and的惯例\g_...
。使用这一惯例的主要原因是 TeX 会在组内设置值时保存它们:将同一控制序列的本地和全局设置混合会导致“保存堆栈累积”,从而导致问题。