\let\foo\relax 和 \def\foo{} 禁用的区别

\let\foo\relax 和 \def\foo{} 禁用的区别

当我希望某个宏(暂时)不执行任何操作时,我通常会写

\let\foo\relax

但有人问我为什么不直接这样做

\def\foo{}

我意识到我无法回答他的问题。

因此,我有两个问题:

  1. 有人能给出一个实际的例子来说明两者在什么情况下会有所不同吗?
  2. 为了禁用宏,两者中哪一个是首选?

下面是我通常使用方法的一个例子:

\let\print@style\relax
\def\setprintstyle#1{\def\print@style{#1}}
\def\print#1{\print@style#1}

答案1

当你

\def\foo{}

你给出了\foo一个空定义,但\foo使用任何用于此目的的测试(例如\ifdefined或 LaTeX 的\@ifundefined)仍然“存在”。通过执行以下操作可以实现相同的效果

\let\foo\empty

它的效率略高一些,因为它指向一个已经使用的内存位置(现在不用担心)。当\foo有这样的定义时,它是可扩展的,所以

\edef\baz{\foo}

将会变得\baz空洞,因为\foo扩展为毫无意义。

另一方面

\let\foo\relax

使\foo等于\relax原语。这是一个“不做任何事”的操作,但重要的是不是可扩展。因此在这种情况下

\edef\baz{\foo}

保留\baz定义 ' \foo'。这可能很有用:这是一种暂时阻止宏执行任何操作同时保留其在其他代码中出现的方式。另一方面,有时您不希望这样:这取决于上下文。当\foo等于时\relax,各种测试是否将其视为“存在”更加多变。TeX 会\relax在各种情况下自动创建等于的控制序列,因此某些测试会将任何等于的内容视为\relax“未定义”。

因此哪个更好取决于您的使用情况。

答案2

第一个让\foo指向\relax,而第二个指向一个空宏。(前提是没有人重新定义\relax\empty。)

\documentclass{article}
\begin{document}
\let\foo\relax
\ifx\foo\relax True\fi
\def\foo{}
\ifx\foo\empty True \fi
\end{document}

为了取消定义,不建议使用

\let\foo\@undefined

在任何阶段你都可以通过以下方式进行测试\meaning

\let\foo\relax
\meaning\foo

将会呈现\relax

编辑

根据修改后的问题。要暂时禁用命令,请放松在组内如图所示:

\def\foo{AAAAAA}
{\let\foo\relax \foo}
\foo

在组内,该命令的含义将等同于\relax不执行任何操作。在组外,它将恢复其值。

相关内容