2010-12-22 4 views
12

Angenommen, Sie möchten eine Lua-Tabelle erstellen, und alle ihre Schlüssel sind gültige lua-Bezeichner. Dann können Sie die key=value Syntax:Lua: implizite Tabellenerstellung mit String Keys - warum die extra Klammern?

local niceTable = { I=1, like=1, this=1, syntax=1 } 

Wenn jedoch die Saiten nicht „erkennbar“ sind, dann müssen Sie die ['key']=value Syntax:

local operators = { ['*']="Why", ['+']="the", ['/']="brackets", ['?']='?' } 

Ich bin ein bisschen darüber verblüfft. Was machen diese Klammern dort? Was meinen sie?

Antwort

18

Sie identifizieren die enthaltene Zeichenfolge als Schlüssel in der resultierenden Tabelle. Die erste Form, könnte man bedenkt, wie gleich

local niceTable = {} 
niceTable.I = 1; 
niceTable.like = 1; 

Die zweite Form gleich

local operators = {} 
operators['*'] = "Why"; 
operators['+'] = "The"; 

Der Unterschied ist rein syntaktischen Zucker, es sei denn, die erste verwendet Bezeichner, so dass er folgen muss die Bezeichnerregeln, die beispielsweise nicht mit einer Zahl und einer Interpretierzeitkonstante beginnen, und die zweite Form eine beliebige alte Zeichenfolge, so dass sie z. B. zur Laufzeit ermittelt werden kann, und eine Zeichenfolge, die keine legale Kennung ist. Das Ergebnis ist jedoch grundsätzlich das gleiche. Die Notwendigkeit für die Klammern ist leicht erklärt.

local var = 5; 
local table = { 
    var = 5; 
}; 
-- table.var = 5; 

Hier ist Var die Kennung, nicht die Variable.

local table = { 
    [var] = 5; 
}; 
-- table[5] = 5; 

Hier ist Var die Variable, nicht die Kennung.

+0

Also ist es im Grunde eine syntaktische Weise, zwischen "dem Wert von var" und dem "var Wert" zu unterscheiden :) Danke für deine Antwort, denke ich Ich verstehe jetzt. Ich denke, ich bevorzuge Rubys Art, Dinge zu tun (es erfordert immer den vollständigen Schlüssel, keine Abkürzungen, aber hat eine Abkürzungssyntax für identifizierbare Zeichenketten) – kikito

17

Die normale Syntax für die Indizierung einer Tabelle ist t[val]. Nur für String-Schlüssel bietet Lua eine alternative-Syntax, wobei t.foo genau äquivalent zu t["foo"] ist. Dies ist eine rein syntaktische Zweckmäßigkeit, der sogenannte "Syntax-Zucker". Es fügt keine Funktionalität hinzu, es gibt Ihnen nur eine weniger überladene Syntax für die Verwendung von Zeichenfolgen als benannte Felder.

Es gibt eine Menge von Strings Tasten dies für nicht:

t["hello_world"] => t.hello_world -- works 
t["hello world"] => t.hello world -- oops, space in the string 
t["5 * 3"]  => t.5 * 3  -- oops 
t['[10]']  => t.[10]   -- oops 

Im Grunde funktioniert es nur, wenn der String-Schlüssel ein gültiger Bezeichner sein würde.

Wieder Tabellen über [] indiziert sind, und in den meisten Fällen müssen Sie sie benutzen:

t = { 
    -- [key]   = value 
    [10]    = "ten", -- number key, string value 
    ["print function"] = print, -- string key, function value 
    ["sub table"]  = {}, -- string key, table value 
    [print]   = 111, -- function key, number value 
    ["foo"]   = 123, -- string key, number value 
} 

Nur wenn Sie einen String-Schlüssel verwenden, die als gültige Kennung (keine Leerzeichen funktionieren würde, enthält nur Wortzeichen, Zahlen oder Unterstreichungen und beginnt nicht mit einer Zahl) können Sie die Abkürzungssyntax verwenden. Für die obige Tabelle wäre das nur 'foo':

t = { 
    -- [key]   = value 
    [10]    = "ten", -- number key, string value 
    ["print function"] = print, -- string key, function value 
    ["sub table"]  = {}, -- string key, table value 
    [print]   = 111, -- function key, number value 
    foo    = 123, -- string key, number value 
} 
+0

[= [[Druck] = 111, - Tabellenschlüssel, Zahlenwert] =] sollte Funktionstaste sein :) – daurnimator

+0

Gute Antwort!die Drucktaste wäre aber eine Funktionstaste ... – jpjacobs

+0

@ jpjacoms, daurnimator: Richtig du bist! Ich habe speziell aus diesem Grund aufgenommen. Kopieren-und-Einfügen-und-vergessen-zu-Editieren-Fehler. Fest. – Mud

Verwandte Themen