이전 글에서 데이터에 이름을 붙여 변수에 저장하고, Lua가 데이터를 어떤 종류로 다루는지 알아보았습니다. 하지만 데이터는 그 자체로 두면 아무 일도 하지 않습니다. 이 데이터에 생명을 불어넣고, 계산하고, 비교하며 새로운 의미를 만들어내는 과정이야말로 프로그래밍의 진정한 재미입니다.
이 모든 작업은 연산자(Operators)와 표현식(Expressions)을 통해 이루어집니다. 연산자는 덧셈, 비교, 논리 판단 같은 특정 작업을 수행하는 기호이며, 표현식은 이러한 연산자와 변수, 값들이 모여 하나의 결과물을 만들어내는 코드 덩어리입니다. 이번 글에서는 Lua에서 사용하는 주요 연산자들을 살펴보고, 이를 조합하여 강력한 표현식을 만드는 방법을 알아보겠습니다.
값으로 변하는 코드, 표현식(Expression)
표현식은 결국 하나의 값으로 평가될 수 있는 모든 코드 조각을 의미합니다. 가장 단순한 형태의 표현식은 값 자체(리터럴)나 변수입니다.
10 -- 숫자 10으로 평가되는 표현식
"Hello" -- 문자열 "Hello"로 평가되는 표현식
local x = 5
x -- 변수 x에 저장된 값, 즉 5로 평가되는 표현식
이러한 기본 요소들에 연산자를 적용하면 더 복잡하고 유용한 표현식을 만들 수 있습니다.
5 + 3 -- 8 이라는 number 값으로 평가됨
x * 2 -- 10 이라는 number 값으로 평가됨
x > 3 -- true 라는 boolean 값으로 평가됨
"Hello" .. " Lua" -- "Hello Lua" 라는 string 값으로 평가됨
not true -- false 라는 boolean 값으로 평가됨
함수 호출 역시 결과값을 반환하므로 그 자체로 하나의 표현식이 됩니다. 표현식은 프로그램의 거의 모든 곳에서 값을 계산하고, 변수에 할당하며, 로직의 조건을 판단하는 데 사용되는 핵심 재료입니다.
Lua 연산자의 종류
Lua는 다양한 상황에 맞춰 사용할 수 있는 여러 종류의 연산자를 제공합니다.
산술 연산자 (Arithmetic Operators)
숫자 값을 계산하는 데 사용됩니다.
+
: 덧셈-
: 뺄셈*
: 곱셈/
: 나눗셈 (결과는 항상 소수를 포함할 수 있는 부동소수점 수)%
: 나머지 (Modulo)^
: 거듭제곱-
: 단항 음수 (부호 변경)//
: 정수 나눗셈 (Lua 5.3 이상, 나눗셈 결과에서 소수 부분을 버림)
local a = 10
local b = 3
print(a + b) -- 출력: 13
print(a / b) -- 출력: 3.333...
print(10 // 3) -- 출력: 3 (정수 나눗셈)
print(a % b) -- 출력: 1 (10을 3으로 나눈 나머지)
print(2 ^ 3) -- 출력: 8 (2의 3제곱)
-- 숫자 형태의 문자열은 자동으로 숫자로 변환하여 계산합니다.
print("5" + 2) -- 출력: 7
관계 연산자 (Relational Operators)
두 값의 관계를 비교하여 true
또는 false
라는 논리 값을 반환합니다.
==
: 두 값이 같음~=
: 두 값이 같지 않음<
: 왼쪽 값이 더 작음>
: 왼쪽 값이 더 큼<=
: 왼쪽 값이 작거나 같음>=
: 왼쪽 값이 크거나 같음
local x = 5
local y = 10
print(x == 5) -- 출력: true
print(x ~= y) -- 출력: true
print(x < y) -- 출력: true
-- 타입이 다르면 값도 다릅니다.
print(5 == "5") -- 출력: false (숫자 5와 문자열 "5"는 다름)
-- 테이블, 함수 등은 내용이 같아도 서로 다른 객체이면 false 입니다.
local t1 = {}
local t2 = {}
local t3 = t1
print(t1 == t2) -- 출력: false (서로 다른 테이블)
print(t1 == t3) -- 출력: true (같은 테이블을 가리킴)
주의: 값을 저장하는 할당 연산자
=
와 값이 같은지 비교하는 관계 연산자==
를 절대 혼동하지 마세요.
논리 연산자 (Logical Operators)
조건을 조합하거나 논리 값을 다룰 때 사용됩니다. Lua의 논리 연산자는 다른 언어와는 다른 독특하고 강력한 특징을 가집니다.
and
: 두 조건이 모두 참일 때 참or
: 두 조건 중 하나라도 참일 때 참not
: 논리 값을 뒤집음 (true
는false
로,false
는true
로)
핵심 특징: Lua에서 false
와 nil
을 제외한 모든 값(숫자 0
이나 빈 문자열 ""
포함)은 true
로 취급됩니다. 또한 and
와 or
는 반드시 true
나 false
를 반환하는 대신, 평가에 사용된 피연산자 중 하나를 그대로 반환합니다.
A and B
:A
가false
나nil
이면A
를 반환하고, 그렇지 않으면B
를 반환합니다.A or B
:A
가false
나nil
이 아니면A
를 반환하고, 그렇지 않으면B
를 반환합니다.
이 특징은 변수에 기본값을 설정할 때 매우 유용하게 사용됩니다.
local loggedInUser = nil
local defaultName = "Guest"
-- loggedInUser가 nil이므로 or 뒤의 값인 defaultName이 선택됨
local displayName = loggedInUser or defaultName
print(displayName) -- 출력: Guest
local activeUser = "Alice"
-- activeUser는 nil이 아니므로 activeUser 자신이 선택됨
displayName = activeUser or defaultName
print(displayName) -- 출력: Alice
-- 'and'는 첫 번째 값이 참이면 두 번째 값을 평가하고 반환합니다.
local hasPermission = true
local actionResult = hasPermission and "작업 실행"
print(actionResult) -- 출력: 작업 실행
문자열 연결 연산자 (Concatenation Operator)
두 개의 문자열을 하나로 이어 붙일 때 사용합니다.
..
: 문자열 연결
local firstName = "Ada"
local lastName = "Lovelace"
local fullName = firstName .. " " .. lastName
print(fullName) -- 출력: Ada Lovelace
-- 숫자는 자동으로 문자열로 변환되어 연결됩니다.
local score = 100
local message = "당신의 점수는 " .. score .. "점입니다."
print(message) -- 출력: 당신의 점수는 100점입니다.
길이 연산자 (Length Operator)
문자열의 글자 수나 테이블의 길이를 구할 때 사용합니다.
#
: 길이 반환
local greeting = "Hello"
print(#greeting) -- 출력: 5
local fruits = {"apple", "banana", "orange"}
print(#fruits) -- 출력: 3
주의: 테이블에서
#
연산자는 인덱스1
부터 중간에 끊김 없이 연속되는 요소의 개수를 세는 것을 원칙으로 합니다. 중간에 인덱스가 비어 있거나(hole) 키가 문자열인 경우에는 길이를 정확하게 예측하기 어려울 수 있습니다.
연산자 우선순위: 계산에도 순서가 있다
하나의 표현식에 여러 연산자가 섞여 있을 때, Lua는 정해진 우선순위 규칙에 따라 계산 순서를 결정합니다. 우선순위가 높을수록 먼저 계산됩니다.
우선순위 (높은 순) | 연산자 |
---|---|
1 | ^ (거듭제곱) |
2 | not # - (단항 연산자) |
3 | * / // % |
4 | + - (덧셈, 뺄셈) |
5 | .. (문자열 연결) |
6 | < > <= >= |
7 | == ~= |
8 | and |
9 | or |
print(5 + 3 * 2) -- 출력: 11 (곱셈이 덧셈보다 우선순위가 높음: 5 + 6)
print(5 > 3 and 10 < 2) -- 출력: false (관계 연산자가 and보다 우선순위가 높음: true and false)
규칙을 모두 외우기보다는, 복잡하거나 혼동될 수 있는 표현식에는 괄호 ()
를 적극적으로 사용하여 계산 순서를 명확히 지정하는 것이 좋습니다. 괄호 안의 표현식은 항상 가장 먼저 계산되며, 코드의 가독성을 크게 향상시킵니다.
print((5 + 3) * 2) -- 출력: 16 (괄호 안을 먼저 계산)
이번 글을 통해 우리는 변수와 값을 가지고 실제적인 작업을 수행하는 연산자와 표현식에 대해 배웠습니다.
- 표현식은 하나의 값으로 평가되는 코드 조각입니다.
- 산술, 관계, 논리, 연결, 길이 연산자 등 다양한 연산자를 사용하여 데이터를 가공하고 비교할 수 있습니다.
- Lua의 논리 연산자는 피연산자를 그대로 반환하는 독특한 특징이 있어 기본값을 설정하는 등에 유용하게 쓰입니다.
- 연산자 우선순위는 계산 순서를 결정하며, 괄호
()
를 사용하면 이를 명확히 제어하고 가독성을 높일 수 있습니다.
이제 우리는 변수와 값으로 의미 있는 결과물을 만들어내는 표현식을 작성할 수 있게 되었습니다.