기본 개념

기본 개념 (Basic Concepts)

루아는 8가지 기본 타입을 제공해요. 이 타입들은 nil, boolean, number, string, function, userdata, thread, table이에요. 각 타입의 의미는 다음과 같아요.

  • nilnil은 값이 없음(부재)을 뜻하는 타입이면서 동시에 그 타입이 가질 수 있는 유일한 값이에요. 전역 변수를 초기화하기 전 상태나, 삭제된 키(delete key)의 값 같은 곳에 등장해요.
  • booleanfalsetrue 두 값만 가져요. 조건 검사에서 nilfalse는 모두 거짓으로 간주되고, 그 외의 모든 값은 참이에요.
  • number — 정수(integer) 또는 실수(float)를 나타내요. 정수는 정확한 정수 열거를 위한 64비트 값이고, 실수는 일반적으로 IEEE 754 더블(double)이에요. 루아는 필요할 때 정수와 실수 사이를 자동으로 변환해요.
  • string — 바이트(byte)의 배열을 나타내요. 루아는 8비트 문자열이므로 어떠한 이진 데이터든 문자열에 저장할 수 있어요. 문자열은 변경 불가능(immutable)한 값이에요. 문자열은 텍스트, 바이트 시퀀스, 그리고 패턴을 나타내는 데 두루 쓰여요.
  • function — 함수를 나타내요. function 타입은 루아로 작성된 함수와 C로 작성된 함수를 모두 가리킬 수 있어요. 루아의 함수는 그 타입에 특별하게 취급되는데, 함수는 호출 가능하면서도 동시에 값으로 취급될 수 있어요 — 변수에 할당하거나, 인자로 전달하거나, 테이블의 필드로 저장할 수 있죠.
  • userdata — C 데이터를 담는 사용자 데이터를 나타내요. full userdata는 루아가 관리하는 메모리 블록을 가리키고, light userdata는 단순히 C 포인터(값 또는 주소)를 가리켜요. userdata는 루아 프로그램이 임의의 C 데이터를 변수에 저장할 수 있게 하는 유일한 방법을 제공해요. userdata는 메타테이블(metatable)을 가질 수 있고, 이 메타테이블을 통해 사용자 정의 연산자나 메서드를 제공할 수 있어요.
  • thread — 독립된 실행 흐름(execution thread)을 나타내요. 루아에서 코루틴(coroutine)을 구현하는 데 쓰이며, 서로 다른 함수 호출 스택을 나타내요.
  • table — 연관 배열(associative array)을 나타내요. 즉 키(key)와 값(value)의 대응 관계를 저장하는 구조예요. 테이블은 변경 가능(mutable)하며, 루아에서 데이터 구조를 표현하는 유일한 메커니즘이에요. 테이블은 배열, 레코드, 사전, 객체 등의 모든 데이터 구조를 표현하는 데 쓰여요.

type 내장 함수를 사용하면 어떤 값의 타입을 알아낼 수 있어요. 예를 들어 type(x)x의 타입을 나타내는 문자열을 반환해요.

모든 값은 다음과 같은 속성을 가져요.

  • 어떤 값이든 테이블의 키로 쓰일 수 있는데, nil은 예외예요. 문자열, 숫자, boolean, 함수, 그 외 값들이 모두 키가 될 수 있어요. 키가 문자열이나 숫자면 그 값 자체가 비교 대상이 되고, 다른 값이면 그 참조(id)가 비교 대상이 돼요.
  • 테이블의 값(또는 전역 변수, 함수, 등)은 nil일 수 있는데, nil인 값은 테이블에 존재하지 않는 것과 같다고 봐요.
  • 불변(immutable) 값과 가변(mutable) 값이 있어요. nil, boolean, number, string은 불변 값이에요. 반면 function, thread, userdata(가변인 것은), table은 가변 값이에요. 어떤 값을 테이블 키로 사용하면, 그 값의 가변성에 관계없이 비교는 값의 동일성(identity)에 기반해요.
  • 어떤 값이든 메타테이블(metatable)과 연결될 수 있는데, nil을 제외한 모든 값은 메타테이블을 가질 수 있어요. 자세한 내용은 metatable 섹션에서 다뤄요.
  • 전역 테이블은 _G로 접근할 수 있어요.

출처: 기본 개념 (Basic Concepts)

본문

값과 타입 (Values and Types)

루아는 동적 타입(dynamically typed) 언어예요. 즉 변수에 타입이 없고, 값에만 타입이 있어요. 따라서 값을 변수에 할당할 때 타입 검사 없이 자유롭게 할 수 있어요. 타입 변환은 저장할 때가 아니라 사용할 때 일어나요. 예를 들어 10 + 1 처럼 산술 연산을 하면 두 피연산자가 모두 숫자여야 하고, 문자열 '1'과 같이 숫자처럼 보이는 문자열을 더하려면 명시적으로 tonumber 같은 함수로 변환해야 해요.

모든 값에 타입이 있지만, 값은 nil일 수 있어요. 값이 nil이면 그 값이 아직 존재하지 않음을 뜻해요. 전역 변수는 초기값이 nil이에요. 변수가 참조되기 전 상태, 테이블에서 존재하지 않는 키에 접근하려 할 때 등에서 nil을 만나요.

루아에서 문자열과 숫자 같은 값은 공유되어 있어요. 즉 같은 문자열 값은 메모리에 한 번만 저장되고, 모든 참조가 그 주소를 공유해요. 이는 값 비교와 메모리 효율에 중요한 의미를 가져요.

코루틴 (Coroutines)

thread 타입은 독립된 실행 흐름을 나타내요. 코루틴은 coroutine.create로 만들 수 있어요. 코루틴은 자신의 실행 상태를 유지하면서, yield를 통해 일시 중단했다가 resume으로 재개할 수 있는 실행 단위예요. 코루틴은 완전히 협력적(cooperative)이에요: 어떤 코루틴도 다른 코루틴을 강제로 중단시킬 수 없어요. 대신 코루틴은 명시적으로 양보(yield)할 때에만 실행을 멈춰요.

없는 값과 존재하는 값 (Absent values)

전역 변수나 테이블 필드, 함수 인자 등에서 nil은 "값이 없다"를 뜻해요. 테이블에서 nil 값을 가진 키는 존재하지 않는 키와 같아요. 문자열 인덱스로 문자열, 숫자 인덱스로 숫자를 접근하지 않는 한, 존재하지 않는 값에 접근하면 nil을 반환해요.

더 알아보기