
在 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} }
會更好。