為變數賦值並檢索它以供以後使用的建議方法是什麼?

為變數賦值並檢索它以供以後使用的建議方法是什麼?

在文件中定義變數並稍後檢索其值的建議方法是什麼?

我用谷歌搜尋了幾種不同的解決方案,通常大約有 10 行長。我想知道,一定有一種更短的方法來做這樣的事情(偽代碼):

\setvalue(VARIABLE1){foo foo bar}

以及稍後在文件中

$\getvalue(VARIABLE1)$.

我還看到過包括定義新命令的解決方案,但是如果該命令已在另一個包中使用怎麼辦?這看起來並不是一個獨立的解決方案。

答案1

好吧,我知道這不是您想要的,但標準路線是帶有 adef或 a newcommand。您提到的問題是全域名稱空間。如果您使用newcommand它,它會告訴您該命令是否已設定(作為編譯中的錯誤,它將命名有問題的newcommand嘗試),從而保護您免受這些問題的影響。

% Set your new variable. In this case it will be 
% called "\MyNewVariable" and the value will be "hello".
\newcommand{\MyNewVariable}{hello}

% Use to get the variable.
\MyNewVariable

如果您可以在它們前面加上您的名字或其他助記符,那麼您就不太可能發生衝突。然後,該助記符將充當您自己的(某種)命名空間。

假設變數的第一個實例設定為 anewcommand且不會引發錯誤,則renewcommand稍後可以使用 a 來變更該變數。

答案2

聽起來您正在尋找一個鍵值系統。我可以建議嗎pgfkeys?包括 Yiannis 對每個變數使用屬性的想法,我會這樣做:

\documentclass{article}
\usepackage{pgfkeys}

\newcommand{\setvalue}[1]{\pgfkeys{/variables/#1}}
\newcommand{\getvalue}[1]{\pgfkeysvalueof{/variables/#1}}
\newcommand{\declare}[1]{%
 \pgfkeys{
  /variables/#1.is family,
  /variables/#1.unknown/.style = {\pgfkeyscurrentpath/\pgfkeyscurrentname/.initial = ##1}
 }%
}

\declare{}

\begin{document}
 \setvalue{VARIABLE1 = foo foo bar}
 \getvalue{VARIABLE1}

 \declare{test/}
 \setvalue{test/property = 12}
 \getvalue{test/property}
\end{document}

即使算上只有大括號的行,也不到十行。操作非常簡單:pgfkeys將變數儲存為「檔案」作為「目錄」;我決定你的應該在/variables目錄中,所以不是在全域命名空間中。 (順便說一句,pgfkeys鍵永遠不會與普通宏名稱衝突,因此它的“全域命名空間”與巨集命名空間不同。)

\setvalue巨集只是適當地更改目錄,然後調用您的分配。該\getvalue巨集從正確的目錄中檢索變數。

唯一的技巧是,在 中pgfkeys,在分配鍵之前需要「已知」它,否則您必須將其稱為key/.initial = value。因為我不想強迫你寫這個,所以我為未知變數創建了一個“處理程序”,它只是在幕後添加了這段程式碼。

您使用 聲明一個具有屬性的變量\declare{variable/},然後您可以variable/property在中用作變量名\setvalue(您也可以用作variable/預設目錄,因此編寫

\setvalue{variable, property 1 = value 1, property 2 = value 2}

這很方便)。該\declare巨集只是為「目錄」設定未知的處理程序/variables/variable/(這表示\declare{}開頭的神秘行設定了/variables/目錄本身)。

答案3

我寧願使用一種 Lisp 方式或物件導向的方式來定義它們。

在下面的最小值中,我們使用:

\setproperty{test}{aproperty}{12}
\getproperty{test}{aproperty}

將它們視為代表test.aproperty(我們實際上將它們定義為 a test@paproperty),這樣它就不太可能與任何現有命令衝突,除了您自己的命令之外:

最小的:

\documentclass{article}
\makeatletter
%  Properties a la Lisp.
\def\ece#1#2{\expandafter#1\csname#2\endcsname}%
% \setproperty{ATOM}{PROPNAME}{VALUE} defines the property PROPNAME on the
% ``atom'' ATOM to have VALUE.
% 
\def\setproperty#1#2#3{\ece\protected@edef{#1@p#2}{#3}}%
\def\setpropertyglobal#1#2#3{\ece\protected@xdef{#1@p#2}{#3}}%
%
% 
% \getproperty{ATOM}{PROPNAME} expands to the value of the property
% PROPNAME on ATOM, or to nothing (i.e., \empty), if the property isn't
% present.
% 
\def\getproperty#1#2{%
  \expandafter\ifx\csname#1@p#2\endcsname\relax
  % then \empty
  \else \csname#1@p#2\endcsname
  \fi
}%
%
\makeatother

\begin{document}
\setproperty{test}{aproperty}{12}
\getproperty{test}{aproperty}
\end{document}

答案4

您的程式碼幾乎是有效的ConTeXt:您使用定義一個變數

\setvalue{variable1}{value}

並且可以使用它的值

\getvalue{variable1}

\@namedef(這些與 LaTeX 中的和類似\@nameuse)。如果您想要鍵值驅動變量,您可以使用:

\definenamespace
    [VAR]
    [
      name=VAR,
      setup=list,
      command=list,
      parent=VAR,
    ]

\setupVAR
    [a={default A},
     b={default B}]

\defineVAR
    [set1]
    [a={set1 A},
     c={set1 C}]

\defineVAR
    [set2]
    [b={set2 B},
     c={set2 C}]

\starttext
\startlines
  \namedVARparameter{set1}{a} % gives set1 A
  \namedVARparameter{set1}{b} % gives default B
  \namedVARparameter{set1}{c} % gives set1 C
\stoplines
\stoptext

相關內容