如何检查命令是否为空(带有变量名)?

如何检查命令是否为空(带有变量名)?

我正在这样做:

\documentclass{article}
\begin{document}
\newcounter{bar}
\newcommand\checkit{
  \ifx\csname foo\romannumeral\the\value{bar}\endcsname\empty
    empty
  \fi
}
\newcommand\foovi{hello}
\setcounter{bar}{6}
\checkit
\renewcommand\foovi{}
\checkit
\end{document}

我得到的是一份空文档,但预期只有一个单词“empty”。这是怎么回事?

答案1

缺少了一个\expandafter。除此之外:如果命令定义为长命令或短命令,则存在差异:

\documentclass{article}
\begin{document}
\newcounter{bar}
\newcommand\checkit{%
  \expandafter\ifx\csname foo\romannumeral\value{bar}\endcsname\empty
    empty
  \fi
}
\newcommand\foovi{hello}
\setcounter{bar}{6}
1. \checkit

\renewcommand\foovi{}
2. \checkit

\renewcommand*\foovi{}
3. \checkit

\end{document}

在此处输入图片描述

答案2

您的代码存在一些问题:

  • \ifx不会扩展其参数,而只会比较其后面的前两个标记(在您的情况下为\csname和 )f,结果始终为 false。您需要使用 来\expandafter构建\csname才能\ifx完成其工作。

  • \empty很短(意味着它不会\long在定义中使用),而使用 创建的宏\newcommand默认为\long。您需要在第一个后面直接使用\newcommand*and 、 or ,而不是。\renewcommand*\newcommand*\def\renewcommand*

  • 您的宏的替换文本以虚假空格开头,您必须注释掉以 结尾的行{,如下所示:\newcommand\checkit{%。您不必注释掉宏名称后的行尾,因此包含\ifx和的行\fi没有问题,另一个(可能)不需要的空格出现在单词 之后empty

\foovi我不知道在尚未定义的情况下应该发生什么,所以我决定让这个案例抛出<false>分支。如果你愿意,你可以轻松地改变它。

我将您的宏定义\checkit为接受两个参数(不是立即接受,而是使用的\@secondoftwo\@secondofthree并且可能\@firstoftwo会接受这些参数)。因此,\checkit{<true>}{<false>}如果宏具有含义\@empty(与相同\empty,但由于我们在,因此\makeatletter我们也可以使用不太可能被重新定义的宏\@empty),则宏现在将表现为并执行相应的分支。

\documentclass[]{article}

\newcounter{bar}

\makeatletter
\providecommand\@secondofthree[3]{#2}
\newcommand\checkit
  {%
    \@ifundefined{foo\romannumeral\value{bar}}%
      {%
        % undefined
        \@secondoftwo % should result in <false>
        %\@firstoftwo % should result in <true>
      }
      {%
        \expandafter\ifx\csname foo\romannumeral\value{bar}\endcsname\@empty
          \expandafter\@secondofthree
        \fi
        \@secondoftwo
      }%
  }
\makeatother

\begin{document}
\setcounter{bar}{6}
\checkit{empty}{not empty}

\newcommand*\foovi{hello}
\checkit{empty}{not empty}

\renewcommand*\foovi{}
\checkit{empty}{not empty}
\end{document}

结果:

在此处输入图片描述

答案3

您被\long状态所困扰。宏\empty为 no \long,相当于\newcommand*\empty{}。但是,您使用的是\renewcommand\foovi因此它是\long且 不\ifx等于\empty。如果您使用 ,\renewcommand*\foovi那么一切都会好起来。

相关内容