루아(Lua) 프로그래밍: 제어 구조 조건과 반복

1 min read

지금까지 우리는 변수에 데이터를 저장하고, 연산자로 이 데이터들을 계산하고 비교하는 방법을 배웠습니다. 하지만 프로그램이 단순히 위에서 아래로 순서대로만 실행된다면, 매우 단순한 작업밖에 할 수 없을 것입니다. 실제 프로그램은 상황에 따라 다른 동작을 하거나, 특정 작업을 여러 번 반복해야 합니다.

이처럼 프로그램의 실행 흐름을 지휘하는 것을 제어 구조(Control Structures) 또는 흐름 제어문이라고 합니다. 제어 구조를 사용하면 코드에 지능을 부여하여, 조건에 따라 분기하거나 특정 코드 블록을 반복 실행하도록 만들 수 있습니다.

이 글에서는 Lua의 핵심 제어 구조인 조건문(if)반복문(while, repeat, for)의 사용법을 자세히 알아보고, 프로그램의 흐름을 더욱 유연하게 만드는 방법을 익혀보겠습니다.

상황에 따른 판단: 조건문 if

if 문은 가장 기본적인 제어 구조로, 주어진 조건이 참인지 거짓인지에 따라 다른 코드를 실행하도록 만듭니다. 마치 “만약 비가 오면, 우산을 챙겨라”와 같은 논리적 판단을 코드에 구현하는 것입니다.

Lua의 진실 혹은 거짓: Lua에서는 falsenil 두 가지 값만이 ‘거짓’으로 간주됩니다. 그 외의 모든 값(숫자 0, 빈 문자열 "" 포함)은 ‘참’으로 취급됩니다.

기본 if

가장 간단한 형태는 if ... then ... end 구조입니다. 조건이 참일 경우에만 thenend 사이의 코드가 실행됩니다.

local temperature = 25

if temperature > 20 then -- 조건: 온도가 20보다 큰가? (참)
  print("날씨가 따뜻합니다.") -- 조건이 참이므로 실행됨
end

if ... else 문 (그렇지 않다면)

조건이 참일 때와 거짓일 때 각각 다른 코드를 실행하고 싶다면 else를 사용합니다.

local age = 15

if age >= 19 then -- 조건: 나이가 19 이상인가? (거짓)
  print("성인입니다.") -- 실행되지 않음
else -- 조건이 거짓일 경우 실행됨
  print("미성년자입니다.")
end

if ... elseif ... else 문 (다양한 조건 검사)

여러 조건을 순서대로 검사하고 싶을 때는 elseif를 사용합니다. if 또는 elseif 조건 중 하나라도 참이 되면 해당 블록의 코드를 실행하고, 나머지 조건은 검사하지 않은 채 if 문 전체를 빠져나옵니다.

local grade = "B"

if grade == "A" then
  print("우수합니다!")
elseif grade == "B" then -- 첫 번째 조건은 거짓, 이 조건은 참
  print("좋습니다!")     -- 이 코드가 실행되고 if문 종료
elseif grade == "C" then
  print("보통입니다.")
else
  print("노력이 필요합니다.")
end

지루한 작업의 자동화: 반복문 (Loops)

반복문은 특정 조건이 만족되는 동안 또는 지정된 횟수만큼 코드 블록을 자동으로 반복 실행합니다. Lua는 while, repeat, for 세 가지 종류의 반복문을 제공합니다.

while 루프: 조건이 참인 동안 반복

while 루프는 주어진 조건이 참인 동안 doend 사이의 코드를 계속해서 반복합니다. 루프에 진입하기 전에 조건을 먼저 검사하므로, 처음부터 조건이 거짓이면 코드는 한 번도 실행되지 않을 수 있습니다.

local count = 1

while count <= 5 do -- 조건: count가 5보다 작거나 같은 동안
  print("현재 카운트: " .. count)
  count = count + 1 -- count 값을 1 증가시켜야 루프가 언젠가 끝납니다.
end

print("while 루프 종료.")
-- 출력: 현재 카운트: 1, 2, 3, 4, 5

경고: while 루프 안에서 조건을 변경하는 코드가 없다면, 조건이 영원히 참으로 유지되어 프로그램이 멈추는 무한 루프에 빠질 수 있습니다. 항상 루프가 종료될 수 있는 조건을 만들어야 합니다.

repeat ... until 루프: 조건이 참이 될 때까지 반복

repeat 루프는 while과 비슷하지만 두 가지 중요한 차이가 있습니다.

  1. 코드를 먼저 실행하고 루프 끝에서 조건을 검사합니다. 따라서 코드는 최소 한 번은 반드시 실행됩니다.
  2. until 뒤의 조건이 참(true)이 되면 루프를 종료합니다. (while은 조건이 거짓이 되면 종료)
local attempts = 0
local password_correct

repeat
  attempts = attempts + 1
  print("시도 " .. attempts .. ": 비밀번호를 확인합니다...")

  -- 3번째 시도에서 성공했다고 가정
  if attempts == 3 then
    password_correct = true
  end
until password_correct == true -- 조건: password_correct가 true가 되면 종료

print("로그인 성공!")
-- 출력: 시도 1, 시도 2, 시도 3을 거친 후 로그인 성공!

for 루프: 가장 구조적인 반복

for 루프는 정해진 횟수만큼 반복하거나, 테이블 같은 데이터 모음의 모든 항목을 순회하는 데 가장 널리 사용되는 반복문입니다. Lua에는 두 가지 형태의 for 루프가 있습니다.

1. 숫자 for 루프

시작값부터 끝값까지 특정 단계(step)만큼 변수 값을 변경하며 반복합니다.

for 변수 = 시작값, 끝값, [단계값] do ... end

  • 단계값을 생략하면 기본값은 1입니다. 음수일 수도 있습니다.
-- 1부터 5까지 1씩 증가
for i = 1, 5 do
  print("i = " .. i)
end

-- 10부터 0까지 2씩 감소
for j = 10, 0, -2 do
  print("j = " .. j)
end

2. 제네릭 for 루프 (테이블 순회)

이터레이터(iterator) 함수를 사용하여 테이블과 같은 컬렉션의 모든 요소를 순회합니다. Lua는 테이블 순회를 위한 유용한 이터레이터 pairsipairs를 기본으로 제공합니다.

  • pairs(테이블): 테이블의 모든 키-값 쌍을 순회합니다. (순서는 보장되지 않음)
local person = { name = "Alice", age = 30, city = "Seoul" }

for key, value in pairs(person) do
  print(key .. ": " .. tostring(value))
end
-- 출력 예시 (순서는 바뀔 수 있음):
-- name: Alice
-- city: Seoul
-- age: 30
  • ipairs(테이블): 테이블의 배열 부분(정수 인덱스 1, 2, 3…)을 순서대로 순회합니다.
local colors = { "red", "green", "blue" }

for index, color in ipairs(colors) do
  print("Index " .. index .. ": " .. color)
end
-- 출력:
-- Index 1: red
-- Index 2: green
-- Index 3: blue

흐름을 끊는 기술: break

때로는 루프가 끝나기 전에 특정 조건이 만족되면 즉시 반복을 중단해야 할 때가 있습니다. 이때 break 키워드를 사용하면 자신을 감싸고 있는 가장 안쪽의 루프 하나를 즉시 빠져나갈 수 있습니다.

local numbers = { 1, 5, 12, 8, 25, 3 }
local target = 8

for index, num in ipairs(numbers) do
  print("확인 중: " .. num)
  if num == target then
    print("목표(" .. target .. ")를 인덱스 " .. index .. "에서 찾았습니다!")
    break -- 목표를 찾았으므로 더 이상 반복할 필요 없음
  end
end

참고: goto 문에 대하여

Lua에는 goto 문도 존재하지만, 코드의 흐름을 예측하기 어렵게 만들고 유지보수를 힘들게 하는 원인이 될 수 있으므로 사용을 극도로 자제하는 것이 좋습니다. 대부분의 경우 if, 루프, break, 함수를 사용해 더 명확하고 구조적인 코드를 작성할 수 있습니다.

이번 글에서는 프로그램의 실행 흐름을 제어하는 핵심적인 방법들을 배웠습니다.

  • if, elseif, else: 조건에 따라 다른 코드를 실행하여 프로그램이 지능적으로 판단하게 합니다.
  • while, repeat, for: 반복적인 작업을 자동화하여 효율성을 높입니다.
  • break: 필요할 때 루프를 탈출하여 흐름을 유연하게 제어합니다.

이러한 제어 구조를 자유자재로 활용하면, 단순히 순서대로만 실행되는 코드를 넘어 다양한 상황에 동적으로 반응하는 강력한 프로그램을 만들 수 있습니다.

루아 Lua 프로그래밍 : 모듈과 패키지 가이드

지금까지 우리는 함수로 코드를 묶고, 테이블로 데이터를 구조화하는 방법을 익혔습니다. 하지만 프로젝트의 규모가 커지기 시작하면, 모든 코드를 단 하나의 파일에 담는 것은 금세 한계에...
eve
53 sec read

루아 (Lua) 프로그래밍: 테이블과 메타테이블의 모든 것

Lua 프로그래밍의 여정에서 가장 중요하고 흥미로운 지점에 도달했습니다. 바로 Lua 언어의 심장이자 가장 중심적인 기능인 테이블(Table)입니다. Lua에는 배열, 딕셔너리, 리스트, 객체 등을 위한 별도의...
eve
1 min read

Lua 프로그래밍: 연산자와 표현식

이전 글에서 데이터에 이름을 붙여 변수에 저장하고, Lua가 데이터를 어떤 종류로 다루는지 알아보았습니다. 하지만 데이터는 그 자체로 두면 아무 일도 하지 않습니다. 이 데이터에...
eve
1 min read