关于 \begingroup\edef\x{\endgroup

关于 \begingroup\edef\x{\endgroup

我看到了代码

\begingroup\edef\x{\endgroup

在回答这个问题

我想了解此方法的用途。在什么情况下应该使用它?

答案1

这里的想法是\edef使用宏(\x)进行扩展,我们不想在“其他地方”更改:你永远不知道还有谁可能在使用\x。因此,需要在组内定义\x。然后,目标是获得组外部的结果,\edef而不对其包含的标记数量做任何假设。\begingroup\endgroup原语不可扩展,因此

\edef\x{%
  \endgroup
  <tokens>%
}

定义\x

> \x=macro:
->\endgroup <expansion of tokens> .

那么,“魔法”构造的结束就是\x

\begingroup
\edef\x{%
  \endgroup
  ....
 }\x

这会将 的定义插入\x到输入流中。 的第一个标记是\endgroup,因此它将在扩展的标记之前恢复 的先前定义\x。 因此最终结果是执行扩展而不产生\x任何影响。 (\x这里“传统上”使用 ,但任何宏名称当然都可以。)

答案2

用法通常是\begingroup\edef\x{\endgroup<code>}\x。这会完全扩展<code>(通常使用 保护某些部分\noexpand)然后对其进行处理。\begingroup\endgroup保留 的定义\x本地化,即 之后 的先前定义\x仍然有效。因此\x仅用作临时存储。

答案3

如果你有类似的东西

\def\XXX#1#2{%
  \begingroup
    % replace with some other important local code
    \global#2=#1
  \endgroup
}

然后\XXX{1.1pt}\bar将全局设置\bar为 1.1pt 的值。有时在当前组内设置值而不是全局设置更有意义,但其他一些代码仍然需要位于更深的组中,那么您可以这样做

\def\YYY#1#2{%
  \begingroup
    % replace with some other important local code
    \edef\x{\endgroup\noexpand#2\number#1}\x
} 

现在\YYY{1.1pt}\bar将设置\bar 不是全局值为 1.1pt,% replace with some other important local code部分仍为局部值。

相关内容