灵感来自关于\let
和的问题\def
,我有一些基本上都归结为问
\def
和之间有什么区别\newcommand
?
我特别想知道
- 是否可以将
\def
可选参数和必需参数传递给 ed 命令? - 是否有
\redef
等效于的命令\renewcommand
? - 我只用过
\newcommand
——有什么理由我应该改变这个习惯吗?
但我欢迎对我可能没有想到的此列表中的任何其他内容发表评论!
答案1
\def
是 TeX 原语,\newcommand
是 之上的 LaTeX 覆盖层\def
。 最明显的好处\newcommand
是\def
:
\newcommand
检查命令是否已经存在\newcommand
允许您定义可选参数
一般来说,任何\newcommand
能做的事情都可以通过来完成\def
,但通常需要一些小技巧,除非你想要做一些\newcommand
做不到的事情,否则没有必要重新发明轮子。
回答您的具体观点:
- 是也不是。使用定义的命令
\def
必须确切地知道它的选项是什么,以及如何将它们呈现给它。然而,TeX 命令可以有点聪明,它会检查一些东西其他而不是它的参数。处理可选命令的方式是查看流中的下一个字符,如果是,[
则调用命令的一个版本,如果不是,则调用另一个版本。因此,如果您准备做一些 hacking,那么可以通过 获得可选参数\def
,但它并不像 那样容易\newcommand
。 - 否。由于
\def
不检查已定义的命令,因此您可以简单地使用\def
again 重新定义内容。要进行检查,您需要使用\@ifundefined
命令(请注意 ampersat (@
) 符号!)。 - 不!
关于差异可能还有很多要说的,但我说的已经足够了。
答案2
添加到安德鲁已经有了很好的响应,唯一\def
可以做但\newcommand
不能做的事情是定义使用括号以外的分隔符的命令。例如,如果您希望能够编写\foo<hello>
并将“hello”解释为参数,您可以编写
\def\foo<#1>{...something with #1...}
您还可以使用命令读取输入下一个支架,例如
\def\foobar#1#{\framebox[#1]}
\foobar 47pt {hello}
想要兼具 的可扩展性\def
和 的易用性\newcommand
,请查看 David Kastrup 的suffix
软件包。当您想要为文档定义自定义标记时,它非常方便。
还请查看 LaTeX3 包xparse
,它以更结构化和更通用的方式介绍了\newcommand
应该如何工作。
答案3
以下是其他答案的要点总结。单击每个答案中的 ▶ 符号可查看更多详细信息。
答案4
一个细微的差别是你不能定义以 开头的命令end
:
\documentclass{article}
\pagestyle{empty}
\newcommand\test{}
\newcommand\endtest{}
\begin{document}
\begin{test}
\end{test}
\end{document}
结果是
! LaTeX Error: Command \endtest already defined.
Or name \end... illegal, see p.192 of the manual.
您始终可以使用来实现此目的。但即使使用而不是 ,\newenvironment
上述代码也不起作用。\providecommand
\newcommand
为什么没有 \provideenvironment?据 Frank Mittelbach 称,这是出于性能考虑——节省内存,20 年前是这样。但现在是\ProvideDocumentEnvironment
从xparse
封装开始的。另外,
与 LaTeX 2ε 的 \newcommand 及其相关函数不同,\DeclareDocumentCommand 函数不会阻止创建以 \end 开头的名称的函数。