Lua 배열 (테이블)이 0 대신 1에서 시작하는 이유는 무엇입니까?


125

나는 Lua의이 부분이 결정한 이유를 이해하지 못합니다. 인덱싱이 1부터 시작하는 이유는 무엇입니까? 나는 (많은 다른 사람들이 그랬듯이) 이 훌륭한 논문 을 읽었습니다 . 배우고 프로그래밍하는 것이 매우 즐거운 언어의 이상한 구석 인 것 같습니다. 오해하지 마십시오. Lua는 훌륭하지만 어딘가에 설명이 있어야합니다. 내가 찾은 것 (웹에서)의 대부분은 인덱스가 1에서 시작한다는 것입니다. Full stop.

디자이너가 그 주제에 대해 말한 것을 읽는 것은 매우 흥미로울 것입니다.

나는 Lua의 "매우"초보자라는 점에 유의하십시오. 테이블에 대해 분명한 것을 놓치고 싶지 않기를 바랍니다.


23
기본 범위도 전역입니다. Lua의 가장 큰 두 가지 잘못된 기능.
Yann Ramin

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 : 테이블에서 사과를 세면 첫 번째 사과는 "하나", 두 번째 사과는 "2"등으로 계산합니다 . 아무도 첫 번째 사과를 "0"으로 계산 한 다음 끝에 하나를 추가하지 않습니다. 0에서 세는 것은 간단하고, 명백하며, 반 직관적입니다. 예, 이것이 인덱싱이 내부적으로 작동하는 방식이라는 것을 알고 있지만 이것이 우리가 추상화라고 부르는 이유입니다.
BlueRaja-Danny Pflughoeft 2013

9
나는 0 기반 인덱싱에 대한 모든 사랑을 이해하지 못했습니다. 오프셋 (시작부터 건너 뛸 항목 수) 및 하위 시퀀스 (0 ≤ x <n)에는 좋지만 기본 항목에는 잘못 보입니다 (두 번째 요소는 1이라고합니다. 열 번째 요소는 인덱스 9에 해당합니까? WAT?) . 프로그래머조차도 컴파일러가보고 한 줄을 찾으려고 할 때 1부터 계산합니다.
marcus

답변:


143

Lua는 컴퓨터 프로그래밍에 대한 공식 교육없이 석유 엔지니어를 위해 설계된 언어 인 Sol의 후손입니다. 컴퓨팅 교육을받지 않은 사람들은 0부터 세는 것이 이상하다고 생각합니다. 1 기반 배열 및 문자열 인덱싱을 채택함으로써 Lua 디자이너는 첫 번째 고객과 후원자의 기대치를 혼란스럽게하는 것을 피했습니다.

저도 처음에는 이상하다고 생각했지만 0 기반 배열을 좋아하는 법을 배웠습니다. 그러나 저는 특히 Lua의 일반 for루프와 ipairs연산자 를 사용하여 Lua의 1 기반 배열을 사용하면 괜찮습니다. 일반적으로 배열이 인덱싱되는 방식에 대해 걱정하지 않아도됩니다.


7
이것은 단지 역사적인 마케팅 이유 일뿐입니다. 특히 현재로서는 합리적인 이유가 없습니다. 그리고 그것을 활용하는 대신 1 기반 인덱싱을 피하려는 것 같습니다. :)
eonil

27
@Eonil은 실제로 명시 적 인덱싱을 피하면 인덱싱 오류를 줄입니다.
Dan D.

8
@ 어닐 역사적 이유는 일반적으로 관련이 있습니다. 무언가로 시작하면 기존의 모든 코드를 망가 뜨리기 때문에 절대 변경할 수 없습니다. 중단 방식이 매우 미묘하기 때문에 0 대 1 인덱싱에 특히 나쁩니다.
CodesInChaos

5
차이점은 1에서 길이로, 0에서 길이 -1로가는 것 사이에 있지만 for 루프 < length에서는 "이상한 0 기반 언어"에서 훨씬 더 편리하고 읽기 쉽습니다. 나는 1에서 반복되는 루프를 보았을 때 고백한다. 나는 즉시 그것이 2 번째 요소에서 시작한다고 가정한다. : S
Felype

45

루아에서 프로그래밍 테이블의 첫 번째 토론, 그들은 언급 :

어떤 값 으로든 테이블을 인덱싱 할 수 있으므로 원하는 숫자로 배열 인덱스를 시작할 수 있습니다. 그러나 Lua에서는 배열을 1 (C에서와 같이 0이 아닌)로 시작하는 것이 일반적이며 여러 기능이이 규칙을 고수합니다.

나중에 데이터 구조에 관한 장에서 그들은 거의 같은 말을합니다 : Lua의 내장 기능은 1 기반 인덱싱을 가정한다는 것입니다.

어쨌든 1 기반 인덱싱을 사용 하면 몇 가지 편리함이 있습니다. 즉, #(길이) 연산자 : t[#t]테이블의 마지막 (숫자) 인덱스에 t[#t+1]액세스 하고 마지막 인덱스를 지나 1에 액세스 합니다. 아직 0 기반 인덱싱에 노출되지 않은 사람에게는 #t+1목록 끝을 지나가는 것이 더 직관적 일 것입니다. 루아의 for i = 1,#t구조 도 있는데 , "길이에 1"이 "길이에 1을 뺀 값"을 인덱싱하는 것보다 더 현명 할 수 있다는 이전 포인트와 같은 범주에 속한다고 생각합니다.

그러나 0 기반 인덱싱의 사고 방식을 깰 수 없다면 Lua의 1 기반 인덱싱은 확실히 더 방해가 될 수 있습니다. 궁극적으로 저자들은 그들에게 효과가있는 무언가를 원 했습니다 . 그리고 나는 그들의 원래 목표가 무엇이 었는지는 모르겠지만 그 이후로 아마도 변경되었을 것입니다.


16

저의 이해는 저자들이 그렇게하는 것이 좋은 방법이라고 생각했기 때문이며, 대중에게 언어를 공개 한 후 결정이 상당히 석회화되었습니다. (나는 그들이 오늘 그것을 바꾸면 지불해야 할 지옥이있을 것이라고 생각한다!) 나는 그 이상의 특별한 정당성을 본 적이 없다.


6
가능한 정당화 : C는 배열이 기본적으로 포인터 및 array[0] == array + 0;이고 배열이 실제로 해시 테이블 일 때 1 기반 계산이 더 자연 스럽기 때문에 그렇게했습니다.
Maygarden 판사는

19
루아 인덱스는 실제로 인덱스입니다. C에서 index라고 할 때 실제로 의미하는 것은 오프셋입니다.
Alex

8

아마도 덜 중요한 점이지만 아직 언급하지 않은 점은 문자열의 첫 번째 문자와 마지막 문자가 각각 0과 -1이 아니라 1과 -1이라는 사실에서 더 나은 대칭이 있습니다.


8
이건 좋지만 1시에 시작한 이유 는 아니었다 .
lhf

3

Lua 라이브러리는 1부터 시작하는 인덱스를 사용하는 것을 선호합니다. 그러나 원하는 모든 인덱스를 사용할 수 있습니다. 0, 1, -5를 사용할 수 있습니다. 설명서에도 나와 있으며 ( https://www.lua.org/pil/11.1.html ) 에서 찾을 수 있습니다 .

사실, 여기서 멋진 것은 내부 루아 라이브러리가 0이 전달 된 일부를 1로 취급한다는 것입니다. ipair를 사용할 때주의하십시오.
그래서 : ("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'있습니까? 그것은 나에게 내장 된 것처럼 보인다.
remram

1
({[0] = 'a', 'b'})[1]
user2262111

0

진짜 이유는이 언어가 포르투갈 법률의 정의를 구현 한 것이며 주요 개발 센터가 브라질에 있었기 때문에 색인이나 첨자로 0 또는 비어 있거나 아무것도 사용하지 않는 것이 선호됩니다. 그러나 언어는 일부 버전의 테이블 생성 함수에서 1이 아닌 시작 인덱스의 사용을 허용합니다.


5
이것이 사실이더라도 Lua가 디자인 된 방식과는 전혀 관련이 없습니다.
lhf 2013-04-20

-1

table [0]은 값을 직접 할당하지 않는 한 항상 nil (null)을 반환합니다. table [0] = 'some value'다음 table [0]은 할당 한 'some value'를 반환합니다.

다음은 예입니다.

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

모든 사람에게 의미가 있습니다.

table = {}

현재 table는 비어 있습니다. 그렇게 할 때

table == {something}

테이블에는 무언가가 포함되어 있으므로 table내가 의미하는 바를 아는 경우 포함 된 내용은 인덱스 1입니다 .

내가 의미하는 바는 table [0]이 존재하고 테이블 = {}입니다. 비어 있습니다. 이제 프로그래머는 빈 테이블을 호출하지 않고 설정 한 다음 채 웁니다. 빈 테이블을 찾는 것은 쓸모가 없습니다. 테이블을 호출 할 때마다 빈 테이블을 만드는 것이 더 간단합니다.

내 영어가 더 나아지지 않을 것이고 그것이 내 최고의 문법입니다. 마음에 들지 않으면 계속 읽지 않아도되지만 도움을 주려는 사람에게 -rep을 주면 사람들은 특히 문법과 같은 것을 전혀 돕고 싶지 않습니다. 저는 문법이 아니라 숫자와 vars의 사람입니다. 죄송합니다.


4
테이블의 값이 0이라는 개념을 이해하지 못했습니다. 테이블의 길이는 0 일 수 있습니다. 그러나 이는 첫 번째 인덱스의 선택과 무관합니다. 나는 사소한 문법 실수에 대해 신경 쓰지 않지만, 당신의 대답의 요점을 이해하지 못하기 때문에 내가 반대표를 던졌습니다.
CodesInChaos

그것이 무엇인지, 테이블은 0 인덱스 또는 값으로 유지 될 수 없습니다. 우리는 그것을 빈 테이블로 사용하기 때문에 <, <당신이 무언가가 1, "n"에서 표현되는 무언가를 가질 때, 그래서 아무것도 없을 때, 당신은 비어 있습니다. 어떤 것의, 어떤 것이 우리를 cero로 인도하지만, cero dosnt는 계산합니다. lua는 실용적 인 길이입니다. 밖에 나가서 친구들에게 내가 그 아티스트의 노래가 무엇인지 알고 있다는 것을 친구에게 말하지 마십시오. 하지마. 점의 테이블 = 빈 테이블 CERO {} 그게
Wesker

5
인덱스 0를 요소로만 사용하는 배열 은 여전히 ​​비어 있지 않습니다. 실제로 lua는 이것을 지원하지만 기본 규칙이 아닙니다.
CodesInChaos

응, 다른 길이에 대해서는 동의하지만 lua는 아니지만 lua 인덱스 0이 존재하지 않으므로 빈 = 0처럼 상상할 수 있습니다. 또는 인덱스를 강제로 0으로 만들 수있을 때도 그게 제가 상상하는 방식입니다. 그것은 테이블 값과 함께 작동하지 않을 것입니다 #table은 0 인덱스를 읽지 않으므로 내 대답은 여전히 ​​루아가 기본적으로 일반 이벤트처럼 만들어졌습니다. 이제 의도하거나 실제로 관련이 없다면 홀 코드를 다시 작성하지 않을 것입니다. 우리는 그것에 대해 아무것도 할 캔트 : /, 난 여전히 공정은 루아의 빈 테이블이 0 인덱스가 말 것을 보라
Wesker
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.