newcommand 在 newcommand 中,变量的值作为参数

newcommand 在 newcommand 中,变量的值作为参数

我创建了一个命令,该命令会创建另一个命令。第一个命令的参数是第二个命令中使用的变量。我希望第二个命令在创建命令时返回变量的值。

\newcommand\testcom[2]{
    \texttt{newcommand #1 : #2}
    \expandafter\newcommand\csname#1\endcsname{#2}
}

\def \test{1} % set 1 to variable 'test'
\testcom{foofoo}{\test} % create command 'foofoo' and display "newcommand foofoo:1" 

\def \test{2} % set 2 to variable 'test'
\testcom{barfoo}{\test} % create command 'barfoo' and display "newcommand barfoo:2"

\def \test{3} % set 3 to variable 'test'

\foofoo % display '3', excepted '1'

\barfoo % display '3', excepted '2'

\barfoo % display '3', excepted '2'

我理解命令\testcom{barfoo}{\test}执行\newcommand\barfoo{\test}但我已经接受\newcommand\barfoo{3}

接下来,我修改了命令以使用来设置中间变量\edef

\newcommand\testcom[2]{
    \texttt{newcommand #1 : #2}
    \expandafter\edef\csname test@#1 \endcsname{#2}
    \expandafter\newcommand\csname#1\endcsname{\csname test@#1 \endcsname}
}

现在,它创建一个\test@barfoo具有该值的变量2,并且命令\barfoo返回该变量。

我想知道是否存在最智能的方法。在我的上下文中,第二种方法newcommand更复杂,\expandafter\edef\csname#1\endcsname{#2}不足以取代newcommand

答案1

由于和都\foofoo定义\barfoo\test,因此如果您更改,它们的输出也会改变\test(如您所演示的那样)。此外,无需创建中间的\test@<cmd>。您只需使用扩展参数即可\edef

在此处输入图片描述

\documentclass{article}

\newcommand\testcom[2]{%
  \texttt{newcommand #1 : #2}%
  \expandafter\edef\csname#1\endcsname{#2}%
}

\begin{document}

\def\test{1} % set 1 to variable 'test'
\testcom{foofoo}{\test} % create command 'foofoo' and display "newcommand foofoo:1" 

\def\test{2} % set 2 to variable 'test'
\testcom{barfoo}{\test} % create command 'barfoo' and display "newcommand barfoo:2"

\def\test{3} % set 3 to variable 'test'

\ttfamily
\string\foofoo: \foofoo % display '1', excepted '1'

\string\barfoo: \barfoo % display '2', excepted '2'

\end{document}

答案2

由于你还没有回答 David Carlisle 评论中的问题,我假设作为\testcom第二个论点,你总是提供一个单个可扩展令牌(一个无参数的宏作为“变量”),并且你总是希望一个宏,它的名字在\testcom第一个参数中提供,从中定义顶层扩展该令牌:

\documentclass{article}
\newcommand\testcom[2]{%
  \texttt{newcommand #1 : \detokenize\expandafter{#2}}%
  \expandafter\newcommand\expandafter*\csname#1\expandafter\endcsname\expandafter{#2}%
}
\begin{document}
\def \test{1} % set 1 to variable 'test'
\testcom{foofoo}{\test} % create command 'foofoo' and display "newcommand foofoo : 1" 

\def \test{2} % set 2 to variable 'test'
\testcom{barfoo}{\test} % create command 'barfoo' and display "newcommand barfoo : 2"

\def\woozle{X}%
\def \test{\woozle}
\testcom{barbar}{\test} % create command 'barbar' and display "newcommand barbar : \woozle"

\def \test{3} % set 3 to variable 'test'

\ttfamily

\string\foofoo=\meaning\foofoo % display '1', excepted '1'

\string\barfoo=\meaning\barfoo % display '2', excepted '2'

\string\barbar=\meaning\barbar % display '\woozle', excepted '\woozle'
\end{document}

在此处输入图片描述

相关内容