expl3 中的「假」變體

expl3 中的「假」變體

假設您有一個對三個令牌進行操作的函數,

\cs_new:Nn \@@_on_three:NNN { #1, #2, #3 }

你有一個變量,其值為三個標記:

\tl_set:Nn \l@@_three_tl { foo }

你想要一個變體

\@@_on_three:V

這樣你就可以說

\@@_on_three:V \l@@_three_tl

但是,如果我沒有弄錯的話,直接\cs_generate_variant會因不同數量的參數(NNNvs.Vx)而感到困惑,並且在任何情況下它都會傳遞擴展的參數大括號內, 正確的?

所以你需要的是一種「假」變體,定義為:

\cs_new:Nn \@@_on_three:V
  { \exp_last_unbraced:Nx \@@_on_three:NNN #1 }

需要明確的是:這有效。我的問題是是否有另一種方法可以做到這一點,而不是那麼「頑皮」——更少的中級欺騙expl3

答案1

定義

\cs_new:Nn \@@_on_three:V
  { \exp_last_unbraced:Nx \@@_on_three:NNN #1 }

是按照程式指南expl3「錯誤」的。類型V變數應與類型基礎函數相關n,並且不應對正在處理的變數的內容做出假設。例如,會發生什麼

\tl_set:Nn \l_@@_three_tl { A }

與給定的定義\@@_on_three:V?另外,您是x-type 擴展而不是V-type 擴展,例如,如果傳遞的變數是 TeX 暫存器或它包含類似 LaTeX2e「受保護」程式碼的內容,則會失敗。

需要明確的是:您並不需要使用它們\cs_generate_variant:Nn來創建變體,但「要求」它們的行為方式與它們的行為方式相同。例如,有各種手動調整的變體l3tl,但這只是為了提高性能,不會改變行為。另請注意,我們最近收緊了許多x-type 變體,因為它們在這方面沒有顯示出正確的結果。

問題沒有說,但讀起來好像tlhere正在用於存儲一些結構化數據,這些數據始終由三個標記組成。因此,似乎想要的是

\cs_new:Nn \@@_on_three:N
  { \exp_last_unbraced:No \@@_on_three:NNN #1 }

其中語意應該與包含三個標記的\@@_on_three:Na 一起使用。tl這是常見的低階工作,類似的程式碼用於例如實驗輸出例程 ( xor) 的部分(我應該對其進行修改)。

相關內容