Tại sao mảng Lua (bảng) bắt đầu bằng 1 thay vì 0?


125

Tôi không hiểu lý do đằng sau quyết định về phần này của Lúa. Tại sao lập chỉ mục bắt đầu từ 1? Tôi đã đọc (như nhiều người khác đã làm) bài báo tuyệt vời này . Đối với tôi, nó dường như là một góc xa lạ của một ngôn ngữ rất thú vị để học và lập trình. Đừng hiểu sai ý tôi, Lua rất tuyệt nhưng phải có lời giải thích ở đâu đó. Hầu hết những gì tôi tìm thấy (trên web) chỉ nói rằng chỉ mục bắt đầu từ 1. Dừng hoàn toàn.

Sẽ rất thú vị khi đọc những gì các nhà thiết kế của nó nói về chủ đề này.

Lưu ý rằng tôi là người mới bắt đầu sử dụng Lua, tôi hy vọng tôi không bỏ lỡ điều gì đó rõ ràng về bảng.


23
Phạm vi mặc định cũng là toàn cầu. Hai sai lầm lớn nhất của Lúa.
Yann Ramin

37
Tôi sẽ không gọi việc bắt đầu từ 1 là một cách gọi sai. Nó thực sự có ý nghĩa hơn - các lập trình viên được đào tạo rất tốt để suy nghĩ về lập chỉ mục dựa trên 0 từ các ngôn ngữ khác mà chúng tôi không thích nó. Chúng tôi cũng được đào tạo để suy nghĩ 5/2 = 2. Điều đó không làm cho nó đúng.
BlueRaja - Danny Pflughoeft

54
@ BlueRaja-DannyPflughoeft: không. Lập chỉ mục bằng 0 có ý nghĩa hơn - con người được đào tạo rất tốt trong việc bắt đầu đếm bằng 1 nên các ngôn ngữ bắt đầu bằng 0 ban đầu rất khó hiểu. Nhưng tôi muốn giới thiệu bạn với Edsger Dijkstra tại đây: cs.utexas.edu/users/EWD/ewd08xx/EWD831.PDF
orlp

11
@nightcracker: Khi đếm táo trên bàn, bạn đếm quả đầu tiên là "một", quả thứ hai là "hai", v.v. Không ai đếm quả đầu tiên là "không" và sau đó thêm một quả vào cuối; đếm từ 0 đơn giản, không thể phủ nhận, phản trực giác. Vâng, tôi nhận ra đó là cách lập chỉ mục hoạt động nội bộ, nhưng đó là lý do tại sao chúng tôi gọi nó là một sự trừu tượng hóa.
BlueRaja - Danny Pflughoeft

9
Tôi chưa bao giờ hiểu tất cả tình yêu đối với việc lập chỉ mục dựa trên 0. Thật tốt cho các hiệu số (có bao nhiêu mục cần bỏ qua từ đầu?) Và các dãy con (0 ≤ x <n), nhưng có vẻ sai đối với những thứ cơ bản (phần tử thứ hai được gọi là một? Phần tử thứ mười tương ứng với chỉ số chín? WAT?) . Ngay cả các lập trình viên cũng đếm từ 1 khi họ cố gắng tìm một dòng được trình biên dịch báo cáo ...
marcus

Câu trả lời:


143

Lua là hậu duệ của Sol, một ngôn ngữ được thiết kế cho các kỹ sư dầu khí không được đào tạo chính quy về lập trình máy tính. Những người không được đào tạo về máy tính nghĩ rằng thật kỳ lạ khi bắt đầu đếm ở con số 0. Bằng cách áp dụng lập chỉ mục chuỗi và mảng dựa trên 1, các nhà thiết kế Lua đã tránh làm nhiễu kỳ vọng của những khách hàng và nhà tài trợ đầu tiên của họ.

Mặc dù lúc đầu tôi cũng thấy chúng kỳ lạ nhưng tôi đã học cách yêu thích các mảng dựa trên 0. Nhưng tôi đồng ý với các mảng dựa trên 1 của Lua, đặc biệt là bằng cách sử dụng forvòng lặp chung của Lua và ipairstoán tử — tôi thường có thể tránh lo lắng về cách các mảng được lập chỉ mục.


7
Đây chỉ là một lý do tiếp thị, lịch sử. Không có lý do hợp lý, đặc biệt là ở thời điểm hiện tại. Và có vẻ như ngay cả khi bạn đang cố gắng để tránh 1 dựa trên chỉ mục thay vì sử dụng nó :)
eonil

27
@Eonil thực sự tránh lập chỉ mục rõ ràng làm giảm lỗi lập chỉ mục.
Dan D.

8
Lý do lịch sử @Eonil thường là những lý do có liên quan. Bạn bắt đầu với một cái gì đó, và sau đó bạn không bao giờ có thể thay đổi nó, bởi vì nó sẽ phá vỡ tất cả các mã hiện có. Đặc biệt không tốt cho việc lập chỉ mục 0 so với 1, vì cách nó phá vỡ khá tinh vi.
CodesInChaos

5
Sự khác biệt là giữa việc đi từ 1 đến Độ dài và từ 0 đến Độ dài -1, nhưng trong vòng lặp for, < lengthnó tiện dụng hơn và dễ đọc hơn nhiều đối với "ngôn ngữ dựa trên 0 bất thường". Tôi thú nhận khi tôi nhìn thấy một iterating vòng từ 1, tôi ngay lập tức cho rằng nó bắt đầu từ yếu tố thứ 2: S
Felype

45

Trong cuộc thảo luận đầu tiên của Lập trình trong Lua về bảng, họ đề cập đến:

Vì bạn có thể lập chỉ mục một bảng với bất kỳ giá trị nào, nên bạn có thể bắt đầu lập chỉ mục của một mảng với bất kỳ số nào vừa ý bạn. Tuy nhiên, trong Lua thường bắt đầu mảng bằng 1 (chứ không phải bằng 0 như trong C) và một số cơ sở tuân theo quy ước này.

Sau đó, trong chương về cấu trúc dữ liệu, họ nói lại gần như tương tự: rằng các cơ sở tích hợp của Lua giả sử lập chỉ mục dựa trên 1.

Dù sao, có một vài tiện ích khi sử dụng lập chỉ mục dựa trên 1. Cụ thể, #(chiều dài) điều hành: t[#t]truy cập cuối cùng (số) chỉ số của bảng, và t[#t+1]truy cập 1 vừa qua chỉ số cuối cùng. Đối với một người chưa tiếp xúc với lập chỉ mục dựa trên 0, #t+1sẽ trực quan hơn nếu di chuyển qua cuối danh sách. Ngoài ra còn có for i = 1,#tcấu trúc của Lua , mà tôi tin rằng thuộc cùng loại với điểm trước đó rằng "1 đến độ dài" có thể hợp lý hơn việc lập chỉ mục "0 đến độ dài trừ 1".

Nhưng, nếu bạn không thể phá vỡ tư duy lập chỉ mục dựa trên 0, thì lập chỉ mục dựa trên 1 của Lua chắc chắn có thể gặp nhiều trở ngại hơn. Cuối cùng, các tác giả muốn một cái gì đó phù hợp với họ ; và tôi thừa nhận rằng tôi không biết mục tiêu ban đầu của họ là gì, nhưng có lẽ nó đã thay đổi kể từ đó.


16

Tôi hiểu rằng đó là cách làm đó chỉ vì các tác giả nghĩ rằng đó sẽ là một cách tốt để làm điều đó, và sau khi họ phổ biến rộng rãi với công chúng, quyết định đó đã trở nên đáng kể. (Tôi nghi ngờ rằng sẽ có địa ngục phải trả nếu họ thay đổi nó ngay hôm nay!) Tôi chưa bao giờ thấy một lời biện minh cụ thể nào ngoài điều đó.


6
Biện minh có thể có: C chỉ làm điều đó bởi vì một mảng về cơ bản chỉ là một con trỏ và array[0] == array + 0;và việc đếm dựa trên 1 sẽ tự nhiên hơn khi mảng thực sự là một bảng băm.
Judge Maygarden

19
Chỉ số Lua thực chất là chỉ số. Trong C khi bạn nói chỉ mục, ý bạn thực sự là một phần bù.
Alex

8

Có lẽ một điểm ít quan trọng hơn, nhưng một điểm mà tôi chưa nghe nói đến: có sự đối xứng tốt hơn trong thực tế là các ký tự đầu tiên và cuối cùng trong chuỗi lần lượt là 1 và -1, thay vì 0 và -1.


8
Mặc dù điều này là tốt, nhưng nó không phải là lý do để bắt đầu lúc 1
lhf

3

Thư viện Lua thích sử dụng các chỉ mục bắt đầu từ 1. Tuy nhiên, bạn có thể sử dụng bất kỳ chỉ mục nào bạn muốn. Bạn có thể sử dụng 0, bạn có thể sử dụng 1, bạn có thể sử dụng -5. Nó thậm chí còn có trong sách hướng dẫn của họ, có thể tìm thấy tại ( https://www.lua.org/pil/11.1.html ).

Trên thực tế, một điều thú vị ở đây là các thư viện lua nội bộ sẽ coi một số số 0 được chuyển thành số 1. Chỉ cần thận trọng khi sử dụng ipairs.
Vì vậy, điều đó: ("abc"):sub(0,1) == "a" and ("abc"):sub(1,1) == "a"sẽ đúng.

 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

Có cách nào để ({'a', 'b'})[1]đánh giá 'b'không 'a'? Điều đó dường như được tích hợp sẵn đối với tôi.
remram

1
({[0] = 'a', 'b'})[1]
dùng2262111

0

Lý do thực sự là ngôn ngữ này là sự triển khai định nghĩa trong luật của Bồ Đào Nha và trung tâm phát triển lớn ở Brazil và sở thích của họ là tránh sử dụng số 0 hoặc trống hoặc không có gì làm chỉ mục hoặc chỉ số dưới. Tuy nhiên, ngôn ngữ này cho phép sử dụng chỉ mục bắt đầu khác với 1 trong chức năng tạo bảng trong một số phiên bản.


5
Ngay cả khi điều này là đúng, nó hoàn toàn không liên quan đến cách Lua được thiết kế.
lhf

-1

table [0] SẼ LUÔN trả về nil (null), KHÔNG THỂ bạn tự gán giá trị cho nó là table [0] = 'some value' và sau đó table [0] sẽ trả về 'some value' mà BẠN đã gán.

Đây là một ví dụ:

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

Nó có ý nghĩa đối với mọi người, rằng nếu

table = {}

Tại thời điểm này, tabletrống rỗng. Vì vậy, khi

table == {something}

Bảng chứa một cái gì đó vì vậy những gì nó chứa là chỉ mục 1 trong tablenếu bạn hiểu ý tôi.

Ý tôi là bảng [0] tồn tại và bảng của nó = {}, cái mà nó trống, bây giờ một lập trình viên sẽ không gọi là một bảng trống, nó đặt chúng và sau đó lấp đầy nó, sẽ vô ích khi tìm thấy một bảng trống bảng bất cứ khi nào bạn muốn gọi nó, vì vậy đơn giản hơn là chỉ cần tạo một bảng trống.

Tiếng Anh của tôi sẽ không khá hơn và đó là ngữ pháp tốt nhất của tôi. Nếu bạn không thích nó, bạn có thể không tiếp tục đọc nó, nhưng đưa -rep cho ai đó đang cố gắng giúp đỡ khiến mọi người không muốn giúp gì cả, đặc biệt là đối với những thứ như ngữ pháp. Tôi là người của những con số và những thứ khác, không phải ngữ pháp. Lấy làm tiếc.


4
Tôi không hiểu về khái niệm bảng có giá trị bằng 0. Một bảng có thể có độ dài bằng 0. Nhưng điều đó không phụ thuộc vào việc lựa chọn chỉ mục đầu tiên. Tôi không quan tâm đến những lỗi ngữ pháp nhỏ, nhưng tôi chỉ đơn giản là không hiểu ý của câu trả lời của bạn, đó là lý do tại sao tôi từ chối.
CodesInChaos

Đó là những gì tôi đề cập, một bảng không thể được giữ với chỉ số hoặc giá trị 0, vì chúng tôi sử dụng nó như một bảng trống <, <khi bạn có một cái gì đó, cái này nó được đại diện từ 1, "n" vì vậy khi bạn không có gì, bạn trống của một cái gì đó, sẽ dẫn chúng ta đến một cero, nhưng số lượng cero không tính, chọn nó là một thứ có chiều dài thực tế, bạn không đi ra ngoài và nói với bạn bè rằng bạn biết tôi có 0 bài hát của nghệ sĩ đó, dù bạn có một số bài hát hay bạn không. the point it table = {} thats cero a blank table
Wesker

5
Một mảng sử dụng chỉ mục 0làm phần tử duy nhất vẫn không trống. Trên thực tế lua hỗ trợ điều này, nó không phải là quy ước mặc định.
CodesInChaos

vâng, tôi đồng ý với bạn, trên một số ngôn ngữ khác, nhưng không phải lua, chỉ số lua 0 không tồn tại, vì vậy chúng ta có thể hình dung nó giống như một rỗng = 0, hoặc đó là cách tôi hình dung nó, ngay cả khi bạn có thể buộc chỉ mục bằng 0, nó sẽ không hoạt động với các giá trị bảng #table sẽ không đọc chỉ mục 0, vì vậy câu trả lời của tôi vẫn là lua của nó về cơ bản được thực hiện như một sự kiện thông thường, bây giờ nếu họ có ý định này hoặc không thì nó không thực sự liên quan, bạn sẽ không viết lại mã lỗ, và chúng tôi không thể làm bất cứ điều gì về nó: /, tôi vẫn luôn tin rằng công bằng của nó để nói rằng trong lua một bảng trống có một chỉ số 0
Wesker
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.