使用函數設定變數和表格

lua-users home
wiki

以下是在書籍「用 Lua 程式設計」中「14.1. 使用動態名稱存取全域變數」中擴充了 setfield 函數 [1]

此函數並非僅確保已經建立的表格存在,它會覆寫任何指定的表格/名稱,這是預期之中。而且由於表格引數是透過參考傳遞,因此你也可以使用 setvar() 處理任何區域表格。

function setvar(Table,Name,Value)

-- Table (table, optional); default is _G
-- Name (string); name of the variable--e.g. A.B.C ensures the tables A
--   and A.B and sets A.B.C to <Value>.
--   Using single dots at the end inserts the value in the last position
--   of the array--e.g. A. ensures table A and sets A[table.getn(A)]
--   to <Value>.  Multiple dots are interpreted as a string--e.g. A..B.
--   ensures the table A..B.
-- Value (any)
-- Compatible with Lua 5.0 and 5.1

   if type(Table) ~= 'table' then
      Table,Name,Value = _G,Table,Name
   end

   local Concat,Key = false,''

   string.gsub(Name,'([^%.]+)(%.*)',
      function(Word,Delimiter)
         if Delimiter == '.' then
            if Concat then
               Word = Key .. Word
               Concat,Key = false,''
            end
            if type(Table[Word]) ~= 'table' then
               Table[Word] = {}
            end
            Table = Table[Word]
         else
            Key = Key .. Word .. Delimiter
            Concat = true
         end
      end
   )

   if Key == '' then
      table.insert(Table,Value)
   else
      Table[Key] = Value
   end
end

測試

> Test = {}
> setvar(Test,'Index',1)
> setvar(Test,'Index.',22)
> setvar(Test,'Index.Index',333)
> table.foreach(Test,print)
Index   table: 0x689668
> table.foreach(Test.Index,print)
1       22
Index   333
>
> setvar(Test,'Index.Index.',4444)
> setvar(Test,'Index.Index.',4444)
> setvar(Test,'Index..',55555)
> setvar(Test,'Index..Index',666666)
> setvar(Test,'Index..Index.',7777777)
> setvar(Test,'Index..Index..',88888888)
> table.foreach(Test,print)
Index..Index..  88888888
Index.. 55555
Index   table: 0x689668
Index..Index    table: 0x684258
> table.foreach(Test.Index,print)
1       22
Index   table: 0x686270
> table.foreach(Test['Index..Index'],print)
1       7777777
>
> setvar(Test,'.Index',999999999)
> table.foreach(Test,print)
Index..Index..  88888888
Index.. 55555
Index   999999999
Index..Index    table: 0x684258
>
> setvar(Test,'',0)
> table.foreach(Test,print)
1       0
Index..Index..  88888888
Index..Index    table: 0x684258
Index   999999999
Index.. 55555

--MarkusHuber


最近變更 · 喜好設定
編輯 · 歷史記錄
最後編輯於格林威治時間 2007 年 5 月 28 日晚上 10:56 (差異)