在下面的 MWE 中,为什么\tl_if_eq:nnTF
如果将操作数直接指定为参数,则函数会按预期执行#..
,但如果先将该参数加载到变量中,然后将该变量用作操作数,则函数会失败?例如,\tl_if_eq:nnTF {#1}{xyz}
如果 ,则产生匹配,#1=abc
但是,\l_rn_auxOne_tl
设置为#1
,则无法产生匹配\tl_if_eq:nnTF {\l_rn_auxOne_tl}{xyz}
。
首先将参数加载到变量中的理由tl
是,在使用它们之前对它们进行测试,以便在可能的情况下预防编译或更糟的运行时错误。例如,这种测试的一个明显用途可能是有效的整数或浮点数语法。
\documentclass{article}
% RN. Tuesday 21 November 2017
% BRIEF DESCRIPTION:
% parameter passing and testing
%=======================
\usepackage[check-declarations]{expl3}
\usepackage{xparse}
%-----------------------
\ExplSyntaxOn
\NewDocumentCommand\myCommand{mO{xyz}}
{
\rn_someUtility:n {#2}
} % \myCommand
\tl_new:N \l_rn_auxOne_tl
\cs_new:Npn \rn_someUtility:n #1
{
\group_begin:
macro~param~1~direct~=~#1\\
\tl_if_eq:nnTF {#1}{xyz}
{match~for~xyz\\}
{no~match~for~xyz\\}
\tl_set:Nn \l_rn_auxOne_tl {#1}
macro~param~1~via~tl~variable~=~#1\\
\tl_if_eq:nnTF {\l_rn_auxOne_tl}{xyz}
{match~for~xyz\\}
{no~match~for~xyz\\}
macro~param~1~direct~=~#1\\
\tl_if_eq:nnTF {#1}{123}
{match~for~123\\}
{no~match~for~123\\}
\tl_set:Nn \l_rn_auxOne_tl {#1}
macro~param~1~via~tl~variable~=~#1\\
\tl_if_eq:nnTF {\l_rn_auxOne_tl}{123}
{match~for~123\\}
{no~match~for~123\\}
\group_end:
} % \rn_someUtility:nnn
\ExplSyntaxOff
%-----------------------
\begin{document}
\textbf{Example~1: }\verb+\myCommand{Hi}+\\
\myCommand{Hi}
\textbf{Example~2: }\verb+\myCommand{Hi}[123]+\\
\myCommand{Hi}[123]
\end{document}
答案1
这就是参数扩展的用途;这是 expl3 代码的主要优势之一,也是函数的参数签名。
\tl_if_eq:nnTF { \l_rn_auxOne_tl } { xyz }
输出 false,因为它是假的,一个人说,xyz
另一个人说\l_rn_auxone_tl
。
如果你想看看里面有什么\l_rn_auxone_tl
,你需要展开它。这就是 expl3 的妙处,你只需告诉函数参数是 类型V
而不是即可做到这一点n
。
\cs_generate_variant:Nn \tl_if_eq:nnTF { V }
然后使用
\tl_if_eq:VnTF \l_rn_auxone_tl { xyz }
对于条件句,我不知道标准程序是什么,但如果你需要其他的,T
你可能需要F
TF
\cs_generate_variant:Nn \tl_if_eq:nnTF { V }
\cs_generate_variant:Nn \tl_if_eq:nnT { V }
\cs_generate_variant:Nn \tl_if_eq:nnF { V }
也许他们可以编写一个\cs_generate_variant:Nnn \tl_if_eq:nnTF { V } { T, F, TF }
? 或类似 ? 的语法{ V ; T, F, TF }
,或者这\cs_generate_variant:Nn \tl_if_eq:nn { V }
对于条件句来说已经足够了?