我正在这样做:
\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
那么一切都会好起来。