\let 与用于自定义宏行为的条件语句

\let 与用于自定义宏行为的条件语句

我收集了大量宏,它们的作用不同,但最终都在内部使用相同的宏(称为此宏\tasks)。有点像这样,但宏名更好:

\newcommand{\aa}{... \tasks}
\newcommand{\bb}{... \tasks}
...
\newcommand{\zz}{... \tasks}

\tasks宏有几个部分需要有条件地执行。可以使用etoolbox或直接使用 来完成\if,如下所示:

\newbool{subtaska}
\newbool{subtaskb}
...
\newcommand{\aa}{... \booltrue{subtaska}\boolfalse{subtaskb} ... \tasks}
\newcommand{\bb}{... \booltrue{subtaska}\booltrue{subtaskb} ... \tasks}
...
\newcommand{\tasks}{
    ...
    \ifbool{subtaska}{...}{}
    \ifbool{subtaskb}{...}{}
    ...
}

但所有这些也可以使用 来完成\let

\newcommand{\subtaska}{...}
\newcommand{\subtaskb}{...}
...
\newcommand{\aa}{... \let\xsubtaska\subtaska\let\xsubtaskb\relax ... \tasks}
\newcommand{\bb}{... \let\xsubtaska\subtaska\let\xsubtaskb\subtaskb ... \tasks}
...
\newcommand{\tasks}{
    ...
    \xsubtaska
    \xsubtaskb
    ...
}

我知道如果需要将参数传递给子任务,使用的方法\let将不起作用,因为\relax(或\@empty)对此不满意,但这对我来说不是问题。

与方法相比,采用条件方法有什么优势吗\let(忽略参数问题\let)?例如,是否有任何性能优势(是的,避免过早优化......)或特殊的额外陷阱?

答案1

如果您想放弃参数,您仍然可以使用\let,但使用\@gobble(或类似方法获得更多参数) 而不是\relax。很明显,\let之后版本效率更高,我认为这只是个人风格的问题。etoolbox \ifbool效率较低的主要原因是它会进行一些健全性检查,以确保第一个参数是声明的布尔开关。但如果您确定不会输入错误并且总是\let分配预期的东西,那么这可能是我会做的。

答案2

实际上,这可能取决于您的条件有多复杂。在简单情况下,subtaska和与它们是否出现在或subtaskb的上下文中无关;但是,您可能需要根据这些宏中的哪一个被扩展来做出进一步的决定,那么最好有一个条件来表示“我们处于这种情况”。\aa\bb

从哲学角度来说,您可能处于设计情况中,您还不确定任务的结构;然后,您可以使用条件语句更好地模拟自己的心理过程。使用该\let方法在代码结构方面非常严格。一旦代码稳定下来,您可能会发现使用命名子任务来简化它的机会。

最哲学的问题是,不同的代码分支是否真的“做同样的事情”但方式不同,或者做着完全不同的事情。第一种情况听起来像是命名子任务的候选;第二种情况听起来像是条件语句的情况。

相关内容