\noexpand、\unexpanded 和 \expandafter

\noexpand、\unexpanded 和 \expandafter

最近我发现了一段代码(来自ucharclasses),使用了三个与扩展相关的宏\noexpand\unexpanded\expandafter

\def\do#1{\noexpand\setTransitionsFor{#1}{####1}{####2}}
\def\doclass#1{
  \begingroup\edef\x{\endgroup
    \noexpand\newcommand
    \unexpanded\expandafter{\csname setTransitionsFor#1\endcsname}[2]%
    {\csname #1Classes\endcsname}}\x}
\ClassGroups

我可以找到一些关于这些宏的参考资料,但我仍然不明白它们到底在做什么。我想知道为什么它们在上面的代码中是必要的,以及为什么我们需要像和中那样的四个升####1####2

答案1

\do表演\noexpand##

\def\do#1{\noexpand\setTransitionsFor{#1}{####1}{####2}}

\edef\z{\do{abc}}
\show\z

由此可见

> \z=macro:
->\setTransitionsFor {abc}{##1}{##2}.
l.4 \show\z

因此,您会看到,在定义csname\z时,它​​被阻止扩展,被替换为此处的参数,并被替换为\edef\setTransitionsFor\noexpand#1\doabc###

对于第二个宏,添加\show\x然后使用 pdflatex 运行此片段

\def\doclass#1{
  \begingroup\edef\x{\endgroup
    \noexpand\newcommand
    \unexpanded\expandafter{\csname setTransitionsFor#1\endcsname}[2]%
    {\csname #1Classes\endcsname}}%
    \show\x
    \x}

\doclass{abc}

生产

> \x=macro:
->\endgroup \newcommand \setTransitionsForabc [2]{\abcClasses }.
\doclass ...csname #1Classes\endcsname }}\show \x 
                                                  \x 
l.9 \doclass{abc}
                 
? x

因此\show临时宏\x将被执行并相当于

\newcommand \setTransitionsForabc [2]{\abcClasses }

abc因此传递给的字符串\doclass已用于构造命令名\setTransitionsForabc\abcClasses

相关内容