\cs_if_exist:NTF 和 \cs_if_free:NTF 之间有什么区别?

\cs_if_exist:NTF 和 \cs_if_free:NTF 之间有什么区别?

我不明白存在和自由有什么区别。请看这个例子:

\documentclass{article}
\usepackage{expl3}

\begin{document}

\ExplSyntaxOn

\cs_new:Npn \my_cs: {}

\verb=\my_cs:= ~ does ~ \cs_if_exist:NF \my_cs: { not ~ } exist \\ % exists
\verb=\my_cs:= ~ is ~ \cs_if_free:NF \my_cs: { not } ~ free \\ % not free

\tl_new:N \l_my_tl

\verb=\l_my_tl= ~ does ~ \cs_if_exist:NF \l_my_tl { not ~ } exist \\ % exists
\verb=\l_my_tl= ~ is ~ \cs_if_free:NF \l_my_tl { not } ~ free % not free

\verb=\l_tmpa_tl=~does~\cs_if_exist:NF \l_tmpa_tl { not ~ } exist \\ % exists
\verb=\l_tmpa_tl=~is~\cs_if_free:NF \l_tmpa_tl { not } ~ free % not free

\ExplSyntaxOff

\end{document}

可以存在 cs是免费的吗?还是说两者的区别更多的是语义上的?

答案1

\cs_show:N \cs_if_free:NTF我展示了和的输出\cs_show:N \cs_if_exist:NTF(格式化以提高可读性)

\cs_show:N \cs_if_free:NTF

> \cs_if_free:NTF=\long macro:
#1->\if_meaning:w #1\scan_stop:
      \prg_return_true:
    \else:
      \if_cs_exist:N #1
        \prg_return_false:
      \else:
        \prg_return_true:
      \fi:
    \fi:
  \c_zero .

\cs_show:N \cs_if_exist:NTF

> \cs_if_exist:NTF=\long macro:
#1->\if_meaning:w #1\scan_stop:
      \prg_return_false:
    \else:
      \if_cs_exist:N #1
        \prg_return_true:
      \else:
        \prg_return_false:
      \fi:
    \fi:
  \c_zero .

如果 的含义#1\relax(又称\scan_stop:),前者返回 true 而后者返回 false,因此\relax是自由的且不存在。否则测试使用\if_cs_exist:N,即 ,\ifdefined结果同样相反。

我认为,进行两个实际上等效的测试只是为了方便,只要切换参数即可。

据约瑟夫·赖特 (Joseph Wright) 称,这两项测试在某个时间点也许不会互相逆转,但现在已经互相逆转了。

答案2

这些命令被特意定义为一对,但它们的行为并不总是对称的。最初的意图是有一个松散的定义,如下所示:

\cs_if_free:NTF- 是吗允许的创建具有此名称的新 cs?
\cs_if_exist:NTF— cs 是否已创建?

很长一段时间以来,\cs_if_free有一些额外的分支来检查其输入是否合理。例如,只有内核应该定义:D带后缀的命令,因此返回 false。实际上可能是唯一的区别:)。您可以根据命名方案的约定想象其他一些这样的检查expl3

在某种程度上,我们认为这一切都是过度的,并简化了行为,此时这两个命令在逻辑上变得对称。但出于风格考虑,我仍然建议根据上述定义在代码中使用它们。

如果我们重新开始,我认为最好只有一个命令名称。

答案3

正如 egreg 所描述的,这两个条件在所有情况下都可以互换使用(当然,最多交换<true>和分支)。<false>

唯一的区别是语义上的。例如,

\tl_new:N \l_foo_tl

以。。开始

\cs_if_free:NF \l_foo_tl { <error> }

\tl_use:N \l_foo_tl

包含大约

\cs_if_exist:NF \l_foo_tl { <error> }

在这两种情况下,我们都试图断言给定的条件成立:要么检查令牌列表变量是否可以自由定义,要么检查令牌列表是否已定义并且在使用时不会触发错误。

相关内容