使用 \@testopt 有什么好处?

使用 \@testopt 有什么好处?

我最近\@testopt发现问题。我尝试了解使用此宏的目的,但在我的调查中,我发现了其他宏,例如\@protected@testopt,甚至是新的软件包,例如exp-testopt。实际上,我只使用 TeX 和 LaTeX2e 进行开发,您觉得这个宏怎么样?

最可靠的方法是什么?

答案1

存在的原因至少有几个\@testopt

如果你看一下的定义\@testopt,你会发现它是

> \@testopt=\long macro:
#1#2->\kernel@ifnextchar [{#1}{#1[{#2}]}.

这使用\kernel@ifnextchar而不是\@ifnextchar:后者可能会被例如 AMS 数学材料重新定义,而 是\kernel@ifnextchar“冻结的”,永远不应该被重新定义。因此\@testopt将始终显示相同的行为,搜索[和跳过空格。从这个意义上讲,使用它而不是自己编写测试可以提高可靠性。

这里的另一个因素是 token 的使用。\@testopt是一个 token,而手动进行测试需要四个 token(\kernel@ifnextchar[[...])。当 LaTeX2e 发布时,token 使用的减少非常重要:内核中有很多地方进行了这样的改动以减小大小。当然,今天这并不重要。

答案2

我认为直接使用没有任何优势\@testopt。你提到的问题有

\def\collecttikzpicture{\@testopt\@collecttikzpicture{}}
\def\@collecttikzpicture[#1]{%
  \global\setbox\tempbox=\hbox\bgroup\begin{tikzpicture}[#1]%
}

功能上等同于

\newcommand\collecttikzpicture[1][]{%
  \global\setbox\tempbox=\hbox\bgroup\begin{tikzpicture}[#1]%
}

并且具有健壮的优点,即在移动参数中使用时,它最终会扩展为自身,这是不是前一个定义的情况。

根据后一种定义,扩展\collecttikzpicture

\@protected@testopt \collecttikzpicture \\collecttikzpicture {}

其中第三个标记是名称中带有反斜杠的特殊控制序列,其作用与上一个定义相同\@collecttikzpicture。因此,您甚至不必担心为实际操作定义辅助控制序列,因为\newcommand会自动处理该问题。当\@protected@testopt展开时,它使用\@testopt,所以\kernel@ifnextchar(而不是\@ifnextchar)。


定义具有强制参数的命令\@testopt非常简单:

\def\foo{\@testopt\@foo{DEFAULT}}
\def\@foo[#1]#2#3{Something with #1, #2, #3}

\foo{X}{Y}让我们看看为什么在和的扩展之后\foo[A]{X}{Y}。这是第一个:

\foo{X}{Y}
\@testopt\@foo{DEFAULT}{X}{Y}
\kernel@ifnextchar [{\@foo}{\@foo[{DEFAULT}]}{X}{Y}
\@foo[{DEFAULT}]{X}{Y}
Something with DEFAULT, X, Y

这是第二个:

\foo[A]{X}{Y}
\@testopt\@foo{DEFAULT}[A]{X}{Y}
\kernel@ifnextchar [{\@foo}{\@foo[{DEFAULT}]}[A]{X}{Y}
\@foo[A]{X}{Y}
Something with A, X, Y

但是当然,

\newcommand{\foo}[3][1]{Something with #1, #2 and #3}

更容易强壮的。

答案3

它可能也与此相关,它\@testopt来自 LaTeX2.09,所以最初所有使用可选参数的 LaTeX 命令都是使用它明确定义的。

和朋友的语法扩展\newcommand允许使用可选参数声明命令,这是较新的 (latex2e) 添加。它们\@testopt在内部使用,但正如 @Joseph 所说,使用更高级别的形式可以节省一些标记并增加稳健性。

相关内容