2009-09-10 16 views
31

W wielu językach można łączyć ciągi znaków przy zmiennych zadaniach. Mam scenariusz, używając języka programowania Lua, gdzie muszę dołączyć dane wyjściowe polecenia do istniejącej zmiennej. Czy w poniższych przykładach istnieje funkcjonalny odpowiednik w języku Lua?Konkatenacja ciągów znaków w języku Lua

Przykłady innych językach:

===== PERL ===== 
$filename = "checkbook"; 
$filename .= ".tmp"; 
================ 

===== C# ===== 
string filename = "checkbook"; 
filename += ".tmp"; 
=============== 

Z góry dziękuję za pomoc.

Odpowiedz

62

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.

1

Łańcuchy mogą być połączone ze sobą za pomocą operatora konkatenacji „..”

ten jest taki sam dla zmiennych myślę

6

Łączenie:

Operator ciąg konkatenacji w lua oznaczamy dwie kropki (".."). Jeśli oba operandy są ciągami lub liczbami, to są one konwertowane na ciągi zgodnie z zasadami wymienionymi w §2.2.1. W przeciwnym razie wywoływany jest metametod "concat" (patrz § 2.8).

od: http://www.lua.org/manual/5.1/manual.html#2.5.4

15

Jeśli pytasz, czy nie ma skróconą wersję operatora .. - no nie ma. Nie można pisać a ..= b. Będziesz musiał wpisać go w całości: filename = filename .. ".tmp"