루아(Lua) 언어를 사용하다 보면 가장 강력하고 유연한 자료구조인 테이블(Table)을 마주하게 됩니다.
이 글에서는 루아 테이블의 기초부터 고급 메타테이블 활용법까지, 실무에서 바로 적용할 수 있는 실전 예제와 함께 자세히 알아보겠습니다.
루아 테이블이란? 기본 개념과 특징
루아에서 테이블은 유일한 복합 자료구조로, 배열과 연관 배열(해시 테이블)의 기능을 모두 수행할 수 있습니다.
자바스크립트의 객체나 파이썬의 딕셔너리와 유사하지만, 더 강력한 메타프로그래밍 기능을 제공합니다.
-- 빈 테이블 생성
local myTable = {}
-- 다양한 방식으로 테이블 생성
local fruits = {"apple", "banana", "orange"}
local person = {name = "김철수", age = 30, city = "서울"}
배열로 사용하는 루아 테이블 실전 예제
루아 테이블을 배열처럼 사용할 때는 1부터 시작하는 인덱스를 가집니다.
이는 C나 파이썬처럼 0부터 시작하는 언어와 다른 특징입니다.
-- 배열 생성과 접근
local numbers = {10, 20, 30, 40, 50}
print(numbers[1]) -- 출력: 10
print(numbers[5]) -- 출력: 50
-- 배열에 요소 추가
table.insert(numbers, 60) -- 끝에 추가
table.insert(numbers, 3, 25) -- 3번째 위치에 삽입
-- 배열 순회
for i = 1, #numbers do
print(i, numbers[i])
end
연관 배열(해시 테이블)로 활용하는 방법
테이블을 연관 배열로 사용하면 문자열이나 다른 값을 키로 사용할 수 있습니다.
이는 객체지향 프로그래밍에서 객체처럼 활용 가능합니다.
-- 연관 배열 생성
local car = {
brand = "Hyundai",
model = "Sonata",
year = 2024,
["fuel-type"] = "hybrid" -- 특수 문자가 포함된 키
}
-- 다양한 접근 방법
print(car.brand) -- 점 표기법
print(car["model"]) -- 대괄호 표기법
print(car["fuel-type"]) -- 특수 문자가 있는 경우 필수
-- 동적으로 키-값 추가
car.color = "silver"
car["price"] = 35000000
중첩 테이블과 복잡한 자료구조 구현
테이블 안에 테이블을 포함시켜 복잡한 자료구조를 만들 수 있습니다.
이는 JSON과 유사한 형태로 데이터를 구조화할 때 유용합니다.
-- 중첩된 테이블 구조
local company = {
name = "Tech Corp",
employees = {
{name = "이영희", position = "개발자", salary = 5000000},
{name = "박민수", position = "디자이너", salary = 4500000},
{name = "김지은", position = "PM", salary = 6000000}
},
departments = {
development = {"이영희", "정수현"},
design = {"박민수"},
management = {"김지은"}
}
}
-- 중첩 테이블 접근
print(company.employees[1].name) -- 출력: 이영희
print(company.departments.development[2]) -- 출력: 정수현
테이블 순회와 반복문 최적화 기법
테이블을 순회하는 방법은 여러 가지가 있으며, 상황에 따라 적절한 방법을 선택해야 합니다.
local inventory = {
apple = 50,
banana = 30,
orange = 25,
grape = 40
}
-- pairs를 사용한 전체 순회 (순서 보장 안됨)
for key, value in pairs(inventory) do
print(key .. ": " .. value .. "개")
end
-- ipairs를 사용한 배열 순회 (1부터 연속된 인덱스만)
local scores = {95, 87, 92, 88, 91}
for index, score in ipairs(scores) do
print("학생 " .. index .. ": " .. score .. "점")
end
-- 커스텀 반복자 구현
function reverseIterator(t)
local i = #t + 1
return function()
i = i - 1
if i > 0 then
return i, t[i]
end
end
end
-- 역순으로 배열 순회
for i, v in reverseIterator(scores) do
print(i, v)
end
메타테이블의 기본 개념과 활용법
메타테이블(Metatable)은 루아의 가장 강력한 기능 중 하나로, 테이블의 동작을 커스터마이즈할 수 있게 해줍니다.
-- 메타테이블 설정 기본 예제
local myTable = {10, 20, 30}
local myMetatable = {
__add = function(t1, t2)
local result = {}
for i = 1, math.max(#t1, #t2) do
result[i] = (t1[i] or 0) + (t2[i] or 0)
end
return result
end
}
setmetatable(myTable, myMetatable)
-- 테이블 덧셈 연산
local otherTable = {5, 10, 15}
local sumTable = myTable + otherTable
-- sumTable은 {15, 30, 45}가 됨
메타메서드를 활용한 고급 프로그래밍
메타테이블의 메타메서드를 활용하면 객체지향 프로그래밍과 유사한 동작을 구현할 수 있습니다.
-- 클래스처럼 동작하는 테이블 구현
local Vector = {}
Vector.__index = Vector
function Vector:new(x, y)
local instance = setmetatable({}, self)
instance.x = x or 0
instance.y = y or 0
return instance
end
function Vector:__add(other)
return Vector:new(self.x + other.x, self.y + other.y)
end
function Vector:__tostring()
return string.format("Vector(%d, %d)", self.x, self.y)
end
-- 사용 예제
local v1 = Vector:new(3, 4)
local v2 = Vector:new(1, 2)
local v3 = v1 + v2
print(v3) -- 출력: Vector(4, 6)
__index와 __newindex 메타메서드 완벽 가이드
__index
와 __newindex
메타메서드는 테이블의 읽기와 쓰기 동작을 제어할 수 있게 해줍니다.
-- 읽기 전용 테이블 구현
local function readonlyTable(t)
local proxy = {}
local mt = {
__index = t,
__newindex = function(t, k, v)
error("읽기 전용 테이블입니다!")
end
}
setmetatable(proxy, mt)
return proxy
end
-- 기본값이 있는 테이블 구현
local function defaultTable(defaultValue)
local mt = {
__index = function(t, k)
return defaultValue
end
}
return setmetatable({}, mt)
end
-- 사용 예제
local config = readonlyTable({debug = true, version = "1.0"})
print(config.debug) -- 정상 동작
-- config.debug = false -- 에러 발생!
local counter = defaultTable(0)
counter.apple = counter.apple + 1 -- 기본값 0에서 시작
print(counter.apple) -- 출력: 1
테이블 메모리 관리와 성능 최적화
대규모 루아 테이블 처리시 메모리와 성능을 고려해야 합니다.
-- 테이블 사전 할당으로 성능 향상
local function createLargeArray(size)
local t = {}
for i = 1, size do
t[i] = 0 -- 미리 공간 할당
end
return t
end
-- 약한 참조 테이블로 메모리 관리
local cache = setmetatable({}, {__mode = "v"}) -- 값이 약한 참조
function getCachedData(key)
local data = cache[key]
if not data then
data = loadDataFromDisk(key) -- 비용이 큰 작업
cache[key] = data
end
return data
end
-- 테이블 재사용으로 가비지 컬렉션 부담 감소
local objectPool = {}
function getObject()
local obj = table.remove(objectPool)
if not obj then
obj = {} -- 새 객체 생성
end
return obj
end
function releaseObject(obj)
-- 객체 초기화
for k in pairs(obj) do
obj[k] = nil
end
table.insert(objectPool, obj)
end
실전 프로젝트에서의 테이블 활용 사례
실제 프로젝트에서 루아 테이블 고급 활용 예제를 살펴보겠습니다.
-- 이벤트 시스템 구현
local EventSystem = {}
EventSystem.__index = EventSystem
function EventSystem:new()
return setmetatable({listeners = {}}, self)
end
function EventSystem:on(event, callback)
if not self.listeners[event] then
self.listeners[event] = {}
end
table.insert(self.listeners[event], callback)
end
function EventSystem:emit(event, ...)
local callbacks = self.listeners[event]
if callbacks then
for _, callback in ipairs(callbacks) do
callback(...)
end
end
end
-- 상태 머신 구현
local StateMachine = {}
StateMachine.__index = StateMachine
function StateMachine:new(states)
local instance = setmetatable({}, self)
instance.states = states
instance.current = nil
return instance
end
function StateMachine:setState(stateName)
if self.current and self.states[self.current].exit then
self.states[self.current].exit()
end
self.current = stateName
if self.states[self.current].enter then
self.states[self.current].enter()
end
end
-- 사용 예제
local gameStates = StateMachine:new({
menu = {
enter = function() print("메뉴 진입") end,
exit = function() print("메뉴 종료") end
},
playing = {
enter = function() print("게임 시작") end,
exit = function() print("게임 종료") end
}
})
gameStates:setState("menu")
gameStates:setState("playing")
마무리
루아 테이블은 단순한 자료구조를 넘어서 메타프로그래밍의 핵심입니다.
배열과 연관 배열의 기본 사용법부터 메타테이블을 활용한 고급 기법까지 마스터하면, 효율적이고 유연한 루아 프로그래밍이 가능해집니다.
이 글에서 소개한 실전 예제들을 프로젝트에 적용해보며 루아 테이블의 강력함을 직접 경험해보세요.
'프로그래밍 언어 실전 가이드' 카테고리의 다른 글
루아 함수와 클로저 – 함수형 프로그래밍 맛보기 (0) | 2025.05.15 |
---|---|
루아(Lua) 프로그래밍 언어 문법 기초: 초보자를 위한 완벽 가이드 (0) | 2025.05.15 |