`\let\A\B` 和 `\let\A=\B` 之间有什么区别吗?

`\let\A\B` 和 `\let\A=\B` 之间有什么区别吗?

我见过有人写这样的东西

\let\original@somemacro=\somemacro

虽然我通常写

\let\original@somemacro\somemacro

它们之间有什么区别吗?

(我相信这个问题肯定是在本网站的其他地方提出来的,但我找不到它。)

答案1

由于您事先知道组件的值,因此您可以非常安全地显式地执行操作,但是在代码(即宏)中,您可能不知道用户可能希望分配什么,如果您不使用作为=分配的一部分,您可能会陷入困境。因此,使用它是个好习惯。

考虑一下这种情况,=在分配中如果没有出现错误\let

\documentclass{article}
\begin{document}
\def\doit#1{\let\X#1}

\doit{=} what?

\X oops
\end{document}

在此处输入图片描述

=将其与将 添加到语法时的输出进行比较\let。啊,这比预期的要多得多:

\documentclass{article}
\begin{document}
\def\doit#1{\let\X=#1}

\doit{=} what?

\X much better
\end{document}

在此处输入图片描述

以下还有另一个案例来强调差异:

\documentclass{article}
\begin{document}
\def\deftok#1#2{\let#1= #2\empty}

\deftok\W{ }

*\W* success

\def\deftok#1#2{\let#1=#2\empty}

\deftok\W{ }

*\W* fail

\def\deftok#1#2{\let#1 #2\empty}

\deftok\W{ }

*\W* fail
\end{document}

在此处输入图片描述

在此示例中,如果您希望对空格进行赋值,则不仅是=命令式, 后面的空格也是命令式。语法还允许对 进行赋值。=\deftok\W{}\empty\W

因此,总而言之,空格和=标记可能会成为有问题的分配,\let必须小心谨慎。我在我的tokcycle软件包 V1.1 中艰难地学到了这个教训。“一朝被坑,二朝被学!”

答案2

前面的答案说明了为什么=在语法中使用它很有用\let。另一个论点是“更清晰”。

=我展示了不同的观点,即在语法中使用 有点不切实际的情况\let:当 的第二个标记\let由 构造时\csname...\endcsname。以下示例是错误的:

\let\foo = \csname bar\endcsname

因为\let扫描其参数时没有扩展:上面的示例确实如此\let\foo=\csname,并且在处理bar\endcsname时会出现错误。因此,我们必须使用链:\endcsname\expandafter

\expandafter\let \expandafter\foo \expandafter=\csname bar\endcsname

\expandafter如果这里用不到的话,可以省掉一个=

\expandafter\let \expandafter\foo \csname bar\endcsame

如果扫描的两个标记都\let必须成对构造,\csname...\endcsname那么我们可以使用另一个技巧,即“\expandafter从对内开始\csname...\endcsname”:

\expandafter\let \csname foo\expandafter\endcsname \csname bar\endcsname

在旧宏中,宏主体中不使用=from语法,因为它会在 TeX 内存中节省一个标记。但这在今天已无关紧要。\let

相关内容