当使用 定义变量时,使用\def
和 使用之间有什么区别吗\define
?当使用方括号内没有数字时,例如\def\somecommand{\percent}
和\define\somecommand{\percent}
?我可以在可以使用 的\define
地方始终使用 吗?\def
答案1
供参考:有两个定义\define
:第一个在
系统辅助文件显示了 Egreg 在他的评论中提到的行为:如果宏已经定义,则保留原样。(配套的宏
\redefine
允许您覆盖宏的当前定义,而不管它是否正在使用。)具有讽刺意味的是,一旦格式加载,这个初步定义就会被毫无保留地覆盖
核心系统.mkiv(而\redefine
永远存在)。
这实际定义
用户界面提供的宏\define
不仅检查先前定义的同名控制序列,而且还作为强制参数的某种简短符号。它具有以下方案
\define [<digit>] <macro> {<definition>}
其中第一个参数是一个数字,指定新宏将接受的参数数量。显然,这可以缩短定义。相比之下,选择器
\def\sevenofnine#1#2#3#4#5#6#7#8#9{#7}
\starttext
\sevenofnine abcdefghi\par
\stoptext
使用宏需要更少的输入\define
:
\define[9]\sevenofnine{#7}
因此这些定义可能会产生更易读的代码 —— 这在编写 TEX 时始终是一件好事。
不幸的是,\define
包装器剥夺了普通的表达能力\def
。在 Context 中,你会注意到,宏采用了可选参数就用户界面而言,这是很常见的。例如,您根本无法
\def
使用以下代码片段中的第二个声明替换为等效表达式
\define
:
\unprotect
\def\myfoo{\dosingleempty\do_my_foo}
\def\do_my_foo[#1]#2{%
\iffirstargument{\bf\WORD#1}\fi
#2\par%
}
\protect
\starttext
\myfoo{bar}
\myfoo[foo]{bar}
\stoptext
这是因为\define
您无法指定参数分隔符(此处:括号)是可选参数所必需的,因此基本上您的宏仅限于采用强制(带括号)参数。出于同样的原因,\{start|stop}something
也没有办法定义廉价环境:
\let\stopfoo\relax
\def\startfoo#1\stopfoo{\bgroup\bold#1\egroup}
%%% ^^^^^^^^ not possible
\starttext
\startfoo
bar
\stopfoo
\stoptext
(其用户界面是\definestartstop
(参见
核心系统.mkiv), 无论如何。)
最后,如今最重要的缺点\define
是它不允许韓國式参数。根本没有办法通过其姓名如果你一开始就不能给它分配一个。
% macros=mkvi
\unprotect
\def\foo{\dosingleempty\do_foo}
\def\do_foo[#optional]#mandatory{%
\bgroup\sansbold#optional\space\egroup
#mandatory\par%
}
\protect
\starttext
\foo{bar}
\foo[foo]{bar}
\stoptext
因此,如果您想进行一些严肃的宏编写,您很快就会学会避免\define
,因为它对于不太复杂的任务来说是安全的。