
假設您有一個對三個令牌進行操作的函數,
\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
會因不同數量的參數(NNN
vs.V
或x
)而感到困惑,並且在任何情況下它都會傳遞擴展的參數大括號內, 正確的?
所以你需要的是一種「假」變體,定義為:
\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 變體,因為它們在這方面沒有顯示出正確的結果。
問題沒有說,但讀起來好像tl
here正在用於存儲一些結構化數據,這些數據始終由三個標記組成。因此,似乎想要的是
\cs_new:Nn \@@_on_three:N
{ \exp_last_unbraced:No \@@_on_three:NNN #1 }
其中語意應該與包含三個標記的\@@_on_three:N
a 一起使用。tl
這是常見的低階工作,類似的程式碼用於例如實驗輸出例程 ( xor
) 的部分(我應該對其進行修改)。