Dlaczego tablice (tabele) Lua zaczynają się od 1 zamiast od 0?

125

Nie rozumiem uzasadnienia decyzji tej części Lua. Dlaczego indeksowanie zaczyna się od 1? Przeczytałem (jak wielu innych) ten wspaniały artykuł . Wydaje mi się, że jest to dziwny zakątek języka, którego bardzo przyjemnie się uczy i programuje. Nie zrozum mnie źle, Lua jest po prostu świetna, ale gdzieś musi być wyjaśnienie. Większość tego, co znalazłem (w sieci), to po prostu stwierdzenie, że indeks zaczyna się od 1. Kropka.

Byłoby bardzo interesujące przeczytać, co powiedzieli na ten temat jego projektanci.

Zauważ, że jestem „bardzo” początkującym graczem w Lua, mam nadzieję, że nie brakuje mi czegoś oczywistego w kwestii stołów.

AraK
źródło
23
Domyślny zakres jest również globalny. Dwie największe niedoskonałości Lua.
Yann Ramin
37
Nie nazwałbym początku od 1 błędem. W rzeczywistości ma to większy sens - programiści są po prostu tak dobrze wyszkoleni, aby myśleć w kategoriach indeksowania opartego na zerach z innych języków, że nam się to nie podoba. Jesteśmy również wyszkoleni w myśleniu 5/2 = 2. To nie czyni tego dobrze.
BlueRaja - Danny Pflughoeft
54
@ BlueRaja-DannyPflughoeft: nie. Indeksowanie zerowe ma więcej sensu - ludzie są tak dobrze wyszkoleni w rozpoczynaniu liczenia od 1, że języki zaczynające się od 0 są początkowo zagmatwane. Ale chciałbym skierować Cię do Edsger Dijkstra tutaj: cs.utexas.edu/users/EWD/ewd08xx/EWD831.PDF
orlp
11
@nightcracker: Kiedy liczysz jabłka na stole, pierwsze z nich liczysz jako „jeden”, drugie jako „dwa” itd. Nikt nie liczy pierwszego jako „zero”, a następnie dodaje je na końcu; liczenie od zera jest po prostu i bezsprzecznie sprzeczne z intuicją. Tak, zdaję sobie sprawę, że tak indeksowanie działa wewnętrznie, ale dlatego nazywamy to abstrakcją.
BlueRaja - Danny Pflughoeft
9
Nigdy nie rozumiałem całej miłości do indeksowania opartego na 0. Dobrze sprawdza się w przypadku przesunięć (ile elementów przeskoczyć od początku?) I podciągów (0 ≤ x <n), ale wygląda źle w przypadku podstawowych rzeczy (drugi element nazywa się jeden? Dziesiąty element odpowiada indeksowi dziewięć? WAT?) . Nawet programiści liczą od 1, kiedy próbują znaleźć wiersz zgłoszony przez kompilator ...
marcus

Odpowiedzi:

143

Lua wywodzi się z języka Sol, języka przeznaczonego dla inżynierów naftowych bez formalnego szkolenia w zakresie programowania komputerowego. Ludzie, którzy nie są wyszkoleni w informatyce, uważają, że rozpoczęcie liczenia od zera jest cholernie dziwne. Przyjmując indeksowanie tablic i ciągów w oparciu o 1, projektanci Lua uniknęli zakłócenia oczekiwań swoich pierwszych klientów i sponsorów.

Chociaż na początku też uważałem je za dziwne, nauczyłem się kochać tablice oparte na 0. Ale radzę sobie dobrze z tablicami Lua opartymi na 1, zwłaszcza używając ogólnej forpętli Lua i ipairsoperatora - zwykle mogę uniknąć martwienia się o to, jak tablice są indeksowane.

Norman Ramsey
źródło
7
To tylko historyczny, marketingowy powód. Brak racjonalnego powodu, szczególnie w obecnym czasie. I wygląda na to, że nawet próbujesz uniknąć indeksowania opartego na 1 zamiast go używać :)
eonil
27
@Eonil faktycznie unikając jawnego indeksowania zmniejsza liczbę błędów indeksowania.
Dan D.
8
Powody historyczne @Eonil są zwykle istotne. Zaczynasz od czegoś, a potem nigdy nie możesz tego zmienić, ponieważ złamałoby to cały istniejący kod. Szczególnie zły dla indeksowania 0 vs 1, ponieważ sposób, w jaki się psuje, jest dość subtelny.
CodesInChaos
5
Różnica polega na przejściu od 1 do Length i od 0 do length -1, ale w pętli for < lengthjest znacznie wygodniejszy i łatwiejszy do odczytania w "dziwnych językach opartych na 0". Wyznaję, kiedy widzę pętlę iterującą od 1, od razu zakładam, że zaczyna się od 2. elementu: S
Felype
45

W pierwszej dyskusji na temat tabel w Programming in Lua wspominają o:

Ponieważ możesz indeksować tabelę z dowolną wartością, możesz rozpocząć indeksy tablicy dowolną liczbą, która Ci się podoba. Jednak w Lua jest zwyczajem, aby rozpoczynać tablice od 1 (a nie od 0, jak w C) i kilka udogodnień jest zgodnych z tą konwencją.

Później, w rozdziale o strukturach danych, ponownie mówią prawie to samo: że wbudowane funkcje Lua zakładają indeksowanie oparte na 1.

W każdym razie istnieje kilka udogodnień związanych z indeksowaniem opartym na 1. Mianowicie, #(długość), operator: t[#t]dostęp ostatnie (numeryczna) indeks do tabeli i t[#t+1]dostęp 1 obok ostatniego indeksu. Dla kogoś, kto nie był jeszcze narażony na indeksowanie oparte na zerach, #t+1byłoby bardziej intuicyjne przejście poza koniec listy. Istnieje również for i = 1,#tkonstrukcja Lua , która, jak sądzę, należy do tej samej kategorii co poprzedni punkt, że „1 do długości” może być bardziej sensowne niż indeksowanie „0 do długości minus 1”.

Ale jeśli nie możesz przełamać mentalności indeksowania opartego na 0, to indeksowanie oparte na Lua 1 może z pewnością być większą przeszkodą. Ostatecznie autorzy chcieli czegoś, co zadziała dla nich ; i przyznaję, że nie wiem, jaki był ich pierwotny cel, ale prawdopodobnie od tego czasu się to zmieniło.

Mark Rushakoff
źródło
16

Rozumiem, że dzieje się tak tylko dlatego, że autorzy myśleli, że byłby to dobry sposób, a po tym, jak udostępnili język opinii publicznej, decyzja ta znacznie się zwapniała. (Podejrzewam, że byłoby piekło do zapłacenia, gdyby dziś to zmienili!) Nigdy nie widziałem innego uzasadnienia poza tym.

dash-tom-bang
źródło
6
Możliwe uzasadnienie: C zrobiło to tylko dlatego, że tablica jest w zasadzie tylko wskaźnikiem i array[0] == array + 0;, a liczenie oparte na 1 jest bardziej naturalne, gdy tablica jest w rzeczywistości tablicą mieszającą.
Sędzia Maygarden
19
Indeksy Lua są w rzeczywistości indeksami. W C, kiedy mówisz indeks, tak naprawdę masz na myśli przesunięcie.
Alex
8

Być może jest to mniej znacząca kwestia, ale o której jeszcze nie słyszałem: jest lepsza symetria w fakcie, że pierwszy i ostatni znak w ciągu mają odpowiednio 1 i -1 zamiast 0 i -1.

VXZ
źródło
8
Chociaż jest to miłe, że to nie powód, począwszy od 1.
LHF
3

Biblioteki Lua wolą używać indeksów zaczynających się od 1. Możesz jednak użyć dowolnego indeksu. Możesz użyć 0, możesz użyć 1, możesz użyć -5. Jest to nawet w ich instrukcji, którą można znaleźć pod adresem ( https://www.lua.org/pil/11.1.html ).

W rzeczywistości, coś fajnego jest to, że wewnętrzne biblioteki Lua będą traktować NIEKTÓRE z pozytywnych zer jako 1. Po prostu zachowaj ostrożność podczas korzystania z ipairs.
Więc to: ("abc"):sub(0,1) == "a" and ("abc"):sub(1,1) == "a"będzie prawdziwe.

 You can start an array at index 0, 1, or any other value:

-- creates an array with indices from -5 to 5
a = {}
for i=-5, 5 do
  a[i] = 0
end
user2262111
źródło
Czy jest jednak sposób, aby ({'a', 'b'})[1]ocenić, aby tego 'b'nie robić 'a'? Wydaje mi się, że to jest wbudowane.
remram
1
({[0] = 'a', 'b'})[1]
user2262111
0

Prawdziwym powodem jest to, że język jest implementacją definicji zawartej w prawie portugalskim, a głównym ośrodkiem rozwoju znajdował się w Brazylii, a oni wolą unikać stosowania zera lub pustego lub nic jako indeksu lub indeksu. Jednak język zezwala na użycie indeksu początkowego innego niż 1 w funkcji tworzenia tabeli w niektórych wersjach.

Deweloper
źródło
5
Nawet jeśli to prawda, nie ma to żadnego znaczenia dla tego, jak zaprojektowano Lua.
lhf
-1

table [0] ZAWSZE zwróci nil (null), chyba że sam przypiszesz do niej wartość table [0] = 'jakaś wartość', a tabela [0] zwróci 'jakąś wartość', którą TY przypisałeś.

Oto przykład:

tbl={'some'}
print('tbl[0]='..tostring(tbl[0]))
print('tbl[1]='..tostring(tbl[1]))
nothing={}
print('nothing[0]='..tostring(nothing[0]))
print('nothing[1]='..tostring(nothing[1]))
nothing[0]='hey'
print('(after assign)\nnothing[0]='..tostring(nothing[0]))
BladeMight
źródło
-11

Dla każdego ma sens, że jeśli plik

table = {}

W tej chwili tablejest pusty. Więc kiedy

table == {something}

Tabela zawiera coś, więc zawiera indeks 1, tablejeśli wiesz, o co mi chodzi.

Miałem na myśli to, że tabela [0] istnieje, a jej tabela = {}, która jest pusta, teraz programista nie nazwie pustej tabeli, ustawia je, a następnie wypełnia, bezcelowe będzie znalezienie pustej tabeli table za każdym razem, gdy chcesz go wywołać, więc łatwiej jest po prostu utworzyć pustą tabelę.

Mój angielski nie poprawi się i to moja najlepsza gramatyka. Jeśli ci się to nie podoba, możesz nie czytać dalej, ale dawanie -rep komuś, kto próbuje pomóc, sprawia, że ​​ludzie w ogóle nie chcą pomagać, szczególnie w przypadku czegoś takiego jak gramatyka. Jestem człowiekiem liczb i zmiennych, a nie gramatyki. Przepraszam.

Wesker
źródło
4
Nie rozumiem, że tabela ma wartość 0. Tabela może mieć długość 0. Ale to jest niezależne od wyboru pierwszego indeksu. Nie obchodzą mnie drobne błędy gramatyczne, ale po prostu nie rozumiem celu twojej odpowiedzi, dlatego zagłosowałem.
CodesInChaos
o to mi chodzi, tabela nie może być przechowywana z indeksem lub wartością 0, ponieważ używamy jej jako pustej tabeli <, <kiedy masz coś, co jest reprezentowane od 1, "n", więc jeśli nie masz nic, twoje puste czegoś, co prowadzi nas do cero, ale cero się nie liczy, lua to język, który jest praktyczny, nie wychodź na zewnątrz i nie mów swoim znajomym, że wiesz, co mam 0 piosenek tych artystów, niezależnie od tego, czy masz jakieś, czy ty nie. punkt jego stół = {} to cero pusty stół
Wesker
5
Tablica, która używa indeksu 0jako jedynego elementu, nadal nie jest pusta. W rzeczywistości lua to obsługuje, po prostu nie jest to domyślna konwencja.
CodesInChaos
tak, zgadzam się z tobą, w niektórych innych językach, ale nie lua, indeks lua 0 nie istnieje, więc możemy sobie to wyobrazić jako pusty = 0, lub tak to sobie wyobrażam, nawet jeśli możesz wymusić indeks na 0, to nie będzie działać z wartościami tabeli #table nie odczyta indeksu 0, więc moja odpowiedź nadal jest taka, że ​​lua jest zasadniczo zrobione jak zwykłe wydarzenie, teraz, jeśli zamierzają to lub nie, to nie jest naprawdę istotne, nie napiszesz ponownie kodu otworu i nie możemy nic z tym zrobić: /, nadal wierzę, że można uczciwie powiedzieć, że w lua pusty stół ma indeks 0
Wesker