\let 和 \def 之间有什么区别?

\let 和 \def 之间有什么区别?

TeX/LaTeX 中的\let和命令有什么区别?\def

最好请提供一个简单的例子来说明它们之间的区别。

答案1

不同之处在于评估“右侧”的时间。

因此\let\foo\bar定义为\foo具有\bar在定义点。另一方面,\def\foo{\bar}实际上定义为\foo具有\bar在使用时

考虑:

\def\bar{hello}
\let\fooi\bar
\def\fooii{\bar}
\fooi +\fooii

\def\bar{goodbye}
\fooi +\fooii

这产生了

hello+hello
hello+goodbye

这是一个简单的过程。

然而,这也是一个微妙的问题,因此可能值得强调几个关键点:

  • 当 TeX 遇到诸如 之类的控制序列时\fooi,它会对其进行评估;如果这些是宏(即,它们已由 定义\def,或\let等于 定义的某个东西\def),那么结果是它们将扩张到其他标记,然后 TeX 将依次检查这些标记,依此类推,直到剩下的是“原始”控制序列或字母(我稍微简化了一点)。

  • \fooi直接扩展到字符hello(因为\bar最初是这样的,并且\fooi被定义为具有相同的价值)。

  • \fooii,相反,扩展为\bar然后立即重新审查并重新扩展。在第一种情况下,\bar扩展为hello,在第二种情况下扩展为goodbye。的定义\fooii没有改变,但\bar在两者之间重新定义了。

  • 清楚了解这个递归扩展的过程是非常在学习如何开发和调试 TeX 宏时很有帮助。

答案2

虽然现有的答案都是正确的,但我想强调一点,这一点还没有明确提到。我自己最近从 Joseph Wright 那里得到了这个信息(见他的回答和我们的评论简单地消除一些 LaTeX 内部混淆)。

正如 Michael 所说,\let\macroa\macrob“复制” 的定义\macrob\macroa。然而,在我看来,这里重要的是,定义实际上并没有被复制,即存在两次,但命令序列\macroa现在指向同一个哈希表输入为\macrob。这意味着\let\macroa\macrob使用更少的内存空间(在早期非常重要,但现在不再重要),并且速度更快,\def\macroa{\macrob}因为在第二种形式中命令序列名称必须在哈希表中解析。

\let实际上“复制”了代币,它们不必是宏/命令序列。这允许定义表示隐式字符的命令序列,例如\let\bgroup={

答案3

它们完全不同。\let将命令复制到新名称,而\def创建新命令。

例如:

\def \foo {bar}

创建一个新命令,运行时\foo进行计算。bar

\let \foo \bar

将命令从\bar命令复制到\foo命令,因此您可以调用其中任何一个。因为它是一个副本(而不是从一个到另一个的指针),所以重新定义\foo不会改变的行为\baz。因此:

\def \foo {bar}
\let \baz \foo
\baz % Outputs 'bar'
\def \foo {new-definition}
\baz % Still outputs 'bar'

相关内容