是否可以将控制序列类型的 LaTeX3 变量的声明与设置其值的行为分开?

是否可以将控制序列类型的 LaTeX3 变量的声明与设置其值的行为分开?

使用标记列表类型的 LaTeX3 变量时,可以声明一个新变量,然后设置其值:

\tl_new:N \g_my_tl
...
\tl_set:Nn \g_my_tl {tokens}

同一模板可与字符串、序列和整数类型的 LaTeX3 变量一起使用。

有没有办法将相同或相似的模板与控制序列类型的 LaTeX 变量一起使用?我想将控制序列变量的声明与设置其值的行为分开。如果控制序列的声明也将其值设置为“未定义”,那就没问题了。

举一个使用示例,假设我想编写一个 LaTeX3 函数\f:NNN,该函数接受三个参数:一个整数变量、一个控制序列变量和一个标记列表变量。我想给这些参数赋予描述性名称。为此,我想通过声明整数、控制序列和标记列表类型的变量来启动我的函数,然后初始化它们,如下所示。

\cs_new:Npn \f:NNN #1#2#3
{
    \int_zero_new:N \l_int
    \cs_clear_new:N \cs_myfunc_l:
    \tl_clear_new:N \l_tl

    \int_set:NN \l_int #1
    \cs_set:NN \cs_myfunc_l: #2
    \tl_set:NN \l_tl #3

    ...
    % Now I can use the variables' names rather than #1, #2, and #3.
    ...
}

答案1

人们总是可以使用\cs_new:Npn\cs_new_protected:Npn定义一个定义,然后更改它们

\cs_new_protected:Npn \foo_demo:Nn #1#2 { }
...
\cs_set_protected:Npn \foo_demo:Nn #1#2 { <actual code> }

通常,这样做是为了

  • 例如“Scratch”功能\cs_tmp:w(用于各种“丢弃”目的)
  • “顶级”函数未被使用但在某些受限环境中的情况(例如,主函数中使用的辅助函数需要“知道”在使用时设置的某些细节)

在设置分隔函数时,我们可能会看到后者

\cs_new_protected:Npn \my_main:nn #1#2
  {
    \cs_set_protected:Npn \__my_aux:nw ##1 #1 ##2 #1
      {
        % Stuff using #1
      }
    \__my_aux:nw #2 #1 #1
  }
\cs_new_protected:Npn \__my_aux:nw { }

请注意,这反映了函数和变量“不同”的事实:大多数情况下,人们会使用\cs_set_eq:NN或存储里面表示tl“可变函数”。因此可以

\cs_new_protected:Npn \__my_saved_function:w { }
% Or perhaps
% \cs_new_eq:NN \__my_saved_function:w \prg_do_nothing:
\int_new:N \l__my_saved_int
\cs_new_protected:Npn \my_public_function:Nn #1#2
  {
    \group_begin:
      \cs_set_eq:NN \__my_saved_function:w #1
      \int_set:Nn \l__my_saved_int {#2}
      % Code using \__my_saved_function:w and \l__my_saved_int
    \group_end:
  }

尽管这会随着任何合理数量的功能分离而变得棘手:人们需要非常小心范围并且不要“重复使用”名称。

相关内容