在 MWE 中:
\documentclass{article}
\setlength{\fboxsep}{0pt}
\begin{document}
\ExplSyntaxOn
\cs_new:Npn \foo:nn #1#2
{
\makebox[#1][s]{#2}
}
% \cs_new:Npn \bar:nn #1#2 { \foo:nn #1#2 }
\let \bar:nn \foo:nn
\fbox{\foo:nn {3cm} {a~b~c~d}}\par
\fbox{\bar:nn {3cm} {a~b~c~d}}
\ExplSyntaxOff
\end{document}
如果我使用\cs_new:Npn
而不是\let
,它会抛出“非法计量单位”错误。为什么?我该如何解决这个问题?
答案1
这是 TeX 语法的问题:
\cs_new:Npn \foo:nn #1#2 { ... }
我展示给你定义 \foo:nn
.但当你称呼你需要做的
\foo:nn {<argument 1>}{<argument 2>}
如果参数由单个标记组成,则可以省略括号。
在你的尝试中,\bar:nn {3cm}{abcd}
你得到
\foo:nn 3cmabcd
也是,结果是#1
3
#2
c
\makebox[3][s]{c}mabcd
这绝对不是你想要的。
\cs_new:Npn \bar:nn #1#2 { \foo:nn {#1}{#2} }
你得到了想要的东西。
观察到\let
不应该使用哪里\cs_new_eq:NN
是正确的调用,让我们比较以下调用:
\cs_new:Npn \bar:nn #1#2 { \foo:nn {#1}{#2} }
\cs_new_eq:NN \bar:nn \foo:nn
有什么区别吗?有很多。第一次调用时,\bar:nn
将使用调用时当前的含义\foo:nn
;第二次调用时,\bar:nn
将使用定义时当前的含义\foo:nn
。所以你需要知道为什么你做了这样的定义并做了适当的选择。如果你确定\foo:nn
永远不会改变含义,那么这两个调用几乎是等效的:并不完全相同,因为使用 1\bar:nn
比使用 2 多需要一个扩展步骤。
笔记。我忽略了一些与问题无关的方面,但它们很重要。
尝试遵循
expl3
命名约定:和\foo:nn
都是\bar:nn
不好的名字。\makebox
使用不可扩展函数/宏的函数应该受到“保护”,例如:\cs_new_protected:Npn \stephen_foo:nn #1#2 { \makebox[#1][s]{#2} }
会更好。