Чому масиви (таблиці) Lua починаються з 1 замість 0?


125

Я не розумію обґрунтування рішення цієї частини Луа. Чому індексація починається з 1? Я прочитав (як і багато інших) цей чудовий документ . Мені здається дивний куточок мови, який дуже приємно вивчати та програмувати. Не зрозумійте мене неправильно, Луа просто чудовий, але десь має бути пояснення. Більшість того, що я знайшов (в Інтернеті), - це лише те, що індекс починається з 1. Повна зупинка.

Було б дуже цікаво прочитати, що сказали його дизайнери з цього приводу.

Зауважте, що я "дуже" новачок у Луа, сподіваюся, що я не пропускаю чогось очевидного щодо таблиць.


23
Область за замовчуванням також глобальна. Дві найбільші недоліки Луа.
Янна Рамін

37
Я б не називав старт у 1 випадковістю. Це насправді має більше сенсу - програмісти просто настільки добре навчені думати з точки зору індексації на основі 0 з інших мов, що нам це не подобається. Ми також навчені думати 5/2 = 2. Це не робить правильним.
BlueRaja - Danny Pflughoeft

54
@ BlueRaja-DannyPflughoeft: ні. Нульове індексування має більше сенсу - люди просто так добре навчені починати рахувати з 1, що мови, які починаються з 0, спочатку плутають. Але я хотів би віднести вас до Edsger Dijkstra тут: cs.utexas.edu/users/EWD/ewd08xx/EWD831.PDF
orlp

11
@nightcracker: Коли ви рахуєте яблука на столі, ви рахуєте перше як "одне", друге - як "два" і т. д. Перший ніхто не вважає "нулем", а потім додає одне в кінці; рахувати з нуля просто, непереривно, контрінтуїтивно. Так, я усвідомлюю, що так працює індексація внутрішньо, але тому ми називаємо це абстракцією.
BlueRaja - Danny Pflughoeft

9
Я ніколи не усвідомлював всю любов до індексації на основі 0. Це приємно для зсувів (скільки предметів пропустити з початку?) Та підрядів (0 ≤ x <n), але виглядає неправильно для основних речей (другий елемент називається один? Десятий елемент відповідає індексу дев'ять? ВАТ?) . Навіть програмісти рахують від 1, коли вони намагаються знайти рядок, про який повідомляв компілятор ...
marcus

Відповіді:


143

Lua походить з Соля, мови, розробленої для інженерів-нафтовиків, які не мають офіційної підготовки з комп'ютерного програмування. Люди, не навчені обчислюванню, вважають, що це проклято дивно починати рахувати з нуля. Скориставшись масивом та індексацією рядків на основі 1, дизайнери Lua уникали збентеження очікувань своїх перших клієнтів та спонсорів.

Хоча я на початку теж вважав їх дивними, я навчився любити масиви на основі 0. Але я добре переживаю масиви на основі Lua, особливо використовуючи загальний forцикл і ipairsоператор Lua - я зазвичай не можу переживати про те, як індексуються масиви.


7
Це лише історична, маркетингова причина. Немає раціональних причин, особливо в поточний час. Здається, навіть ви намагаєтесь уникати індексації на основі 1, а не використовувати :)
eonil

27
@Eonil фактично уникає явного індексування, зменшує помилки індексації.
Ден Д.

8
@Eonil історичні причини, як правило, є відповідними. Ви починаєте з чогось, а потім вже не можете його змінити, оскільки це порушило б усі існуючі коди. Особливо погано для індексування 0 проти 1, оскільки спосіб його розбиття є досить тонким.
CodesInChaos

5
Різниця полягає в переході від 1 до довжини і від 0 до довжини -1, але в циклі a для циклу < lengthнабагато зручніше і легше читати на "weirdo 0-мовах на основі". Зізнаюсь, коли бачу цикл, що повторюється з 1, я одразу припускаю, що він починається з 2-го елемента: S
Феліпе,

45

У програмуванні в першому обговоренні таблиць Луа вони згадують:

Оскільки ви можете індексувати таблицю будь-яким значенням, ви можете запустити індекси масиву з будь-якого числа, яке вам подобається. Однак у Луї прийнято починати масиви з 1 (а не з 0, як у С), і кілька об'єктів дотримуються цієї конвенції.

Пізніше, у розділі про структури даних, вони знову повторюють майже те саме: вбудовані засоби Lua передбачають індексацію на основі 1.

У будь-якому випадку є кілька зручностей використання 1-індексованої індексації. А саме #оператор (довжина): отримує t[#t]доступ до останнього (числового) індексу таблиці та має t[#t+1]доступ до 1 минулого останнього індексу. Для тих, хто ще не зазнав індексації на основі 0, #t+1було б більш інтуїтивно просуватися в кінці списку. Є також for i = 1,#tконструкція Луа , яка, на мою думку, підпадає під ту ж категорію, що і попередня точка, що "1 на довжину" може бути більш розумним, ніж індексувати "0 до довжини мінус 1".

Але, якщо ви не можете зламати настрій індексації на основі 0, то індексація на основі Lua, безумовно, може стати більш перешкодою. Зрештою, автори хотіли чогось, що для них працювало ; і я визнаю, що не знаю, якою була їх початкова мета, але, мабуть, вона змінилася з того часу.


16

Я розумію, що це саме так, тому що автори подумали, що це буде хорошим способом, і після того, як вони розкриють мову для громадськості, це рішення значно кальцифікується. (Я підозрюю, що було б пекло заплатити, якби вони змінили його сьогодні!) Я ніколи не бачив особливого виправдання поза цим.


6
Можливе обґрунтування: C зробив це лише тому, що масив є в основному лише вказівником і array[0] == array + 0;, а підрахунок на основі 1 є більш природним, коли масив справді є хеш-таблицею.
Суддя Мейґарден

19
Індекси Луа - це фактично індекси. У С, коли ви кажете індекс, те, що ви насправді маєте на увазі, це зміщення.
Олексій

8

Можливо, менш вагомий момент, але я ще не чув про згадане: краща симетрія полягає в тому, що перший і останній символи в рядку знаходяться на рівні 1 і -1 відповідно замість 0 і -1.


8
Хоча це добре, але це не було причиною для початку в 1.
lhf

3

Бібліотеки Lua вважають за краще використовувати індекси, які починаються з 1. Однак ви можете використовувати будь-який індекс, який хочете. Можна використовувати 0, можна використовувати 1, можна використовувати -5. Це навіть є в їх посібнику, який можна знайти за посиланням ( https://www.lua.org/pil/11.1.html ).

Насправді, щось класне тут - внутрішні бібліотеки луа вважають ДЕЯКІ пройдені 0 як 1. Будьте обережні, використовуючи ipairs.
Так що: ("abc"):sub(0,1) == "a" and ("abc"):sub(1,1) == "a"буде правдою.

 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

Чи є спосіб зробити так, щоб ({'a', 'b'})[1]оцінювання 'b'не було 'a'? Це здається мені вбудованим.
ремрам

1
({[0] = 'a', 'b'})[1]
користувач2262111

0

Справжня причина полягає в тому, що мова є втіленням цього визначення в закон Португалії, а головний центр розвитку був у Бразилії, і їх перевага - це уникати використання нуля або порожнього або нічого в якості індексу або підписки. Однак мова дозволяє використовувати індекс запуску, відмінний від 1, у таблиці створення функції в деяких версіях.


5
Навіть якщо це правда, це зовсім не має значення для того, як Lua був розроблений.
lhf

-1

таблиця [0] ВЖЕ ВІДПОВІДАЄТЬ нуль (null), БІЛЬШЕ, якщо ви самі присвоїте йому значення таблиці [0] = 'деяке значення', а потім таблиця [0] поверне 'деяке значення', яке Ви призначили.

Ось приклад:

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]))

-11

Для кожного має сенс, що якщо a

table = {}

На даний момент tableпорожній. Тому, коли

table == {something}

У таблиці міститься щось, тому воно містить індекс 1, tableякщо ви знаєте, що я маю на увазі.

Що я мав на увазі, що ця таблиця [0] існує, а її таблиця = {}, яка порожня, тепер програміст не буде називати порожню таблицю, вона встановлює їх, а потім заповнює її, буде марно знайти порожню таблицю кожного разу, коли ви хочете її викликати, тому її простіше просто створити порожню таблицю.

Моя англійська не покращиться, і це моя найкраща граматика. Якщо вам це не подобається, ваше вільне не продовжуйте його читати, але надаючи -реп для того, хто намагається допомогти, змушує людей взагалі не бажати допомоги, особливо для чогось на зразок граматики. Я людина чисел і змін, а не граматики. Вибачте.


4
Я не вважаю, що таблиця оцінюється 0. Таблиця може мати довжину 0. Але це не залежить від вибору першого індексу. Мене не хвилюють незначні граматичні помилки, але я просто не розумію суть вашої відповіді, саме тому я заперечував.
CodesInChaos

ось що я маю, таблицю не можна тримати з індексом 0 або значенням, оскільки ми використовуємо це як порожню таблицю <, <коли у вас є щось це щось, представлене з 1, "n", тому коли у вас нічого немає, ваш порожній чогось, що веде нас до серо, але цедо донс графа, lua це довга мова, яка стає практичною, ти не виходиш на вулицю і скажи своїм друзям, що ти знаєш, що у мене є 0 пісень тих артистів, що ти маєш, чи ти не точка його таблиця = {} ось це порожній стіл
Вескер

5
Масив, який використовує індекс 0як лише елемент, все ще не порожній. Насправді Луа це підтримує, це просто не умова за замовчуванням.
CodesInChaos

Так, я погоджуюся з вами, на деяких інших мовах, але не в луа, індекс lua 0 dosnt існує, тому ми можемо уявити це як порожнє = 0, або ось як я малюю його, навіть коли ви можете змусити індекс дорівнювати 0, він не буде працювати з табличними значеннями #table не буде читати індекс 0, тому моя відповідь його все-таки, що lua його в основному робиться як звичайний захід, тепер, якщо вони мають намір це чи ні, це не дуже актуально, ви не будете знову писати код дірки, і ми не можемо з цим нічого робити: /, я все ще вірю, що справедливо сказати, що в Луа порожній стіл має індекс 0
Wesker
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.