언어 — 변수

언어 — 변수 (The Language — Variables)

변수(variable)는 값을 저장하는 이름이에요. 루아에는 세 종류의 변수가 있어요: 전역 변수(global variable), 지역 변수(local variable), 테이블 필드(table field). 테이블 필드는 테이블 값의 특정 키에 대응하는 항목으로, 변수처럼 읽고 쓸 수 있어요.

변수 이름(name)은 식별자이므로, 변수는 그 이름(문자열 키)으로 전역 환경의 테이블에서 조회돼요. 전역 변수 name은 사실 _ENV.name의 축약 표현이에요 (2.2 절 참조).

변수의 종류

  • 전역 변수(global): 가장 바깥쪽 환경에서 접근되는 변수예요. _ENV를 통해 조회되고, 어디서든 읽고 쓸 수 있어요. 초기값은 nil이에요.
  • 지역 변수(local): local 키워드로 선언된 변수예요. 선언된 블록(block) 안에서만 접근할 수 있어요. 지역 변수는 스택과 유사하게 동작하고, 블록을 벗어나면 더 이상 접근할 수 없어요.
  • 테이블 필드(table field): t[k] 형태로 테이블 t의 키 k에 접근하는 변수예요. t가 테이블이면 t[k]는 그 필드를 읽거나 쓸 수 있어요.

변수의 종류는 선언 위치와 키워드에 따라 구분돼요.

  • 전역 변수: 블록 밖에서 이름으로 접근.
  • 지역 변수: local name으로 선언.
  • 테이블 필드: t.k 또는 t[k] 형태.

지역 변수 (Local variables)

지역 변수는 local 키워드로 선언하고, 블록 안에서만 유효해요.

local x = 10
do
  local x = 20      -- 새 지역 변수 x (블록 안에서만)
  print(x)          --> 20
end
print(x)            --> 10

지역 변수는 선언된 지점부터 그 블록의 끝까지 범위(scope)를 가져요. 또한 지역 변수는 선언과 동시에 초기화할 수도 있고, 여러 개를 한 번에 선언할 수도 있어요.

local a, b = 1, 2
local c, d   -- 둘 다 nil로 초기화

지역 변수를 같은 이름으로 다시 선언하면, 안쪽 선언이 바깥쪽을 가려요 (shadowing).

테이블 필드 (Table fields)

변수는 테이블의 필드일 수도 있어요. Prefixexp.name 또는 Prefixexp[exp] 형태가 그 예예요.

t = {}          -- 전역 테이블
t.x = 10        -- 필드 x 할당
t["y"] = 20     -- 문자열 키 y
print(t.x, t["y"])   --> 10 20

t.namet["name"]의 문법적 설탕(syntactic sugar)이에요. 필드 접근 시 t[k]에서 키가 없으면 __index 메타메서드가, 할당 시 키가 없으면 __newindex 메타메서드가 개입할 수 있어요 (2.4 절 참조).

전역 변수의 의미

전역 변수는 어디서 접근하든 동일한 문자열 키로 전역 테이블을 조회해요. 전역 변수에 값을 할당하면 전역 테이블에 그 키로 저장돼요. 따라서 서로 다른 함수나 모듈이 같은 전역 이름을 읽으면 같은 값을 공유할 수 있어요.

counter = 0        -- 전역 변수 counter
function inc()
  counter = counter + 1
end

가시성 규칙 요약

  • 지역 변수는 선언 블록 안에서만 보여요.
  • 전역 변수는 _ENV 테이블을 통해 어디서든 보여요.
  • 지역 변수가 전역 변수나 바깥 지역 변수를 가릴 수 있어요.
  • 블록(do ... end), 함수 본문, for 루프의 제어 변수, while/repeat 본문 등은 각각 새로운 지역 변수 스코프를 도입해요.

출처: 변수 (Variables)

본문

할당 (Assignment)

변수에 값을 넣는 것은 할당(assignment)으로, varlist = explist 형태예요. 할당은 먼저 모든 표현식(explist)을 평가하고, 그다음에 왼쪽 변수들에 값을 순서대로 대입해요. 따라서 오른쪽 표현식들은 왼쪽 변수에 값을 넣기 전에 모두 계산돼요.

i = 3
i, a[i] = i+1, 20    -- i는 4가 되고, a[3]이 20이 됨 (i=3일 때 읽음)

할당의 왼쪽 변수 개수와 오른쪽 값 개수가 다르면 조정(adjustment) 규칙이 적용돼요: 값이 더 많으면 잘리고(맨 앞에서부터 왼쪽 변수 수만큼), 값이 더 적으면 nil로 채워져요. 그리고 테이블 필드 할당 시 __newindex 메타메서드가 개입할 수 있어요.

루프 제어 변수

for 루프의 제어 변수는 for 문의 스코프 안에서만 유효한 지역 변수예요. 자세한 내용은 "For 문장" 절에서 다뤄요.

더 알아보기