Jak powiedziano w innych odpowiedziach, operator konkatenacji ciągów w Lua ma dwie kropki.
Twój prosty przykład byłby napisany tak:
filename = "checkbook"
filename = filename .. ".tmp"
Istnieje jednak pewien wyjątek być świadomi. Ponieważ łańcuchy w Lua są niezmienne, każda konkatenacja tworzy nowy obiekt typu string i kopiuje do niego dane z łańcuchów źródłowych. To sprawia, że kolejne konkatenacje w jednym ciągu mają bardzo słabe wyniki.
Lua idiom w tym przypadku jest coś takiego:
function listvalues(s)
local t = { }
for k,v in ipairs(s) do
t[#t+1] = tostring(v)
end
return table.concat(t,"\n")
end
zbierając ciągi być łączone w tablicy t
, biblioteka standardowa rutyna table.concat
może być stosowany do łączenia ich wszystkich (wraz z ciąg separatora między każdą parą) bez niepotrzebnego kopiowania ciągów.
Aktualizacja: Właśnie zauważyłem, że pierwotnie napisał fragment kodu powyżej używając pairs()
zamiast ipairs()
.
Jak pierwotnie napisano, funkcja listvalues()
rzeczywiście produkuje każdą wartość z przekazanej tabeli, ale nie w stabilnej lub przewidywalnej kolejności. Z drugiej strony, zawierałoby wartości, których klucze nie były dodatnimi liczbami całkowitymi w zakresie od 1
do #s
. To właśnie robi: tworzy każdą pojedynczą parę (klucz, wartość) zapisaną w tabeli.
W większości przypadków, gdy używasz czegoś w rodzaju listvaluas()
, byłbyś zainteresowany zachowaniem ich zamówienia. Tak więc wywołanie napisane jako listvalues{13, 42, 17, 4}
wytworzyłoby ciąg zawierający te wartości w tej kolejności.Jednak tego nie zrobi pairs()
, to wyszczególni je w pewnej kolejności, która zależy od podstawowej implementacji struktury danych tabeli. Wiadomo, że zamówienie zależy nie tylko od kluczy, ale również od kolejności włożenia kluczy i usunięcia innych kluczy.
Oczywiście ipairs()
również nie jest idealną odpowiedzią. Wylicza tylko te wartości tabeli, które tworzą "sekwencję". Oznacza to, że te wartości, które są kluczami, tworzą nieprzerwany blok obejmujący od 1 do pewnej górnej granicy, która jest (zwykle) także wartością zwracaną przez operatora #
. (W wielu przypadkach funkcja ipairs()
sobie lepiej zastąpić prostszą for
pętlę, która po prostu liczy się od 1
do #s
. Jest to zalecana praktyka w Lua 5.2 iw LuaJIT gdzie prostsze for
pętla może być bardziej efektywnie wdrożone niż ipairs()
iterator .)
Jeśli naprawdę dobrym podejściem jest pairs()
, zwykle jest tak, że chcesz wydrukować zarówno klucz, jak i wartość. Zmniejsza to obawy o zamówienie poprzez samoopisywanie danych. Oczywiście, ponieważ dowolny typ Lua (z wyjątkiem nil
i zmiennoprzecinkowy NaN
) może być użyty jako klucz (i NaN
może być również zapisany jako wartość), znalezienie reprezentacji ciągów jest pozostawione jako ćwiczenie dla ucznia. I nie zapomnij o drzewach i bardziej złożonych strukturach stołów.