\relax 和 {} 之间有什么区别?

\relax 和 {} 之间有什么区别?

据我所知, 的目的\relax是阻止宏吞噬后续材料(例如空格)。但{}( \bgroup\egroup) 具有相同的功能。为什么我们需要两者?

答案1

尝试以下几个例子:

\documentclass{article}

\begin{document}

\[
\begin{array}{rl}
+9mm   & +9m^2 \\
[+9mm] & [+3m]^2 \\{}
+9mm   & +9m^2 \\{}
[+9mm] & [+3m]^2 \\\relax
+9mm   & +9m^2 \\\relax
[+9mm] & [+3m]^2
\end{array}
\]

\end{document}

在此处输入图片描述

  • 如果您将\\其保留在那里,则将[+9mm]被解释为的可选参数\\并转换为垂直空间。
  • 如果使用{},则会在公式中插入“空值”,并且+间距不正确。
  • 这里只有带有的变体可以\relax正常工作,因为它实际上什么也不做。

可以使用非常相似的例子来表明这是和扩展等\relax的正确终止符。\dimexpr\numexpr

答案2

这个问题很难回答,因为这两个结构几乎在各个方面都不同,所以这是一个从哪里开始的问题。

\relax是一个单独的标记,一个不可扩展的 TeX 原语,执行时不执行任何操作。 {}是两个标记(假设标准 catcodes)标记一个 TeX 组或非分隔的宏参数。

  • \baselineskip =13pt\relax停止\relax长度解析器向前查看plusminus组件,但不执行其他任何操作。\baselineskip =13pt{}将以相同的方式定义baselineskip,但然后打开和关闭一个组,这可能会产生几种影响,最明显的是在数学模式下它将生成一个空的数学原子并影响周围原子的间距。

  • {\let\section\relax...\immediate\write\@auxout{.. \section}}使诸如\section本地惰性的命令可以安全地(作为其自身)写入辅助文件。{\let\section{}...\immediate\write\@auxout{.. \section}}做一些事情但不太可能做任何人想要的事情:-)

  • \relax是赋予由生成的新控件名称的定义,\csname 因此常用\expandafter\ifx\csname foo\endcsname\relax来测试宏是否已定义。这显然与使用{}

  • $a+{}$产生中缀间距,因为{}生成一个数学原子。$a+\relax$就像$a+$和不产生中缀间距一样+

答案3

原因不止一个。

我来举个例子,看看哪个\relax是好的,{}哪个不是:

\def\mysize{144pt\relax} % when expanding \mysize we won't trigger
                         % expansion of the next token
\hbox to \mysize{\hfil abc\hfil}

当 TeX 处理\hbox命令时,它会扩展后面的标记to以找到所需的<dimen>;它会找到144pt\relax并根据语法规则让它\relax消失(用 TeX 的术语来说,它是一个<filler>);

\def\mysize{144pt{}}

TeX 会发现

\hbox to 144pt{}{\hfil abc\hfil}

这将是一场灾难。

当然也可以定义

\def\mysize{144pt }

但这样\mysize就不能在文本中使用\unskip。也许这是一个有点牵强的例子。

无论如何,\relax实际上什么都不做,同时{}打开和关闭一个组。

您提到\bgroup\egroup等同于{}:但事实并非如此;例如,带有 finds 参数的宏{}将吸收一个空参数,而\bgroup\egroup将吸收\bgroup作为参数,留\egroup在流中。同样,如果我们使用\relax它,它将是一个标记。

相关内容