ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Lua] Type (자료형) 알아보기
    Lua 2024. 10. 4. 17:23

    Lua는 동적 타입 언어 입니다. 모든 값에 타입이 지정되어 있으므로, 변수를 선언할 때 타입을 지정하지 않습니다.

    Lua의 기본 타입은 nil, boolean, number, string, function, table, thread, userdata의 8가지가 있습니다.

    print(type("Hello world!")) -- string
    print(type(1.1))            -- number
    print(type(123))            -- number
    print(type(print))          -- function
    print(type(type))           -- function
    print(type(true))           -- boolean
    print(type(nil))            -- nil

    type()함수를 통해 인자로 전달한 값의 type을 알 수 있습니다.

    특이사항으로, type함수가 반환하는 값의 type은 string입니다. type을 통한 조건문 등을 작성할 때 주의해주세요.

     

    이번 글에서는 각각의 타입에 대해 간단히 살펴보도록 하겠습니다.

     


     

    1. nil

     

    타 언어의 null, nullptr등과 유사합니다.

    nil타입은 nil 한가지의 값만 가지는 타입이며, 값이 없는 상태를 나타냅니다.

    위 특성으로 인해, 기존 값을 삭제할 때 nil을 대입할 수 있습니다.

     

    2. boolean

     

    참과 거짓을 표현하는 타입입니다.

    true와 false의 두 가지 값을 가질 수 있습니다.

    하지만, Lua는 다른 값으로도 참과 거짓을 나타낼 수 있습니다.

    더보기

    조건문 등의 제어 구문에서 이러한 특징을 확인할 수 있습니다.

    코드를 살펴보겠습니다.

    if 0 then end    -- true
    if nil then end  -- false
    if "" then end   -- true
    if 123 then end  -- true

    Lua에서 false를 의미하는 값으로는 boolean타입의 false값 뿐만 아니라, nil 또한 사용할 수 있습니다.

    그 외 다른 언어에서 false로 사용될 수 있는 0, ""등의 값은 true가 될 수 있다는 점에 주의해주세요.

     

    3. number

     

    실수를 표현하는 타입입니다.

    Lua는 정수와 실수 타입을 따로 구분하지 않습니다.

    수치의 정밀도의 경우 IEEE 754 표준 (부동 소수점)을 따르고 있습니다.

    따라서 실수의 경우 정확한 표현이 불가능한 경우에만 라운드 처리가 발생하며, 정수의 경우 문제 없이 표현 가능합니다.

    또한, 실수부에 지수부를 더하는 과학적 표기법을 사용할 수 있습니다.

    더보기

    다음과 같은 e표기법을 사용할 수 있습니다.

    print(type(3.2e+7))  -- number
    print(3.2e+7)        -- 32000000

    다음과 같이 0x를 접두사로 사용하여 16진수 표기법을 사용할 수 있습니다.

    print(type(0x3a.b2))  -- number
    print(0x3a.b2)        -- 58.6953125
    print(type(0x1p+16))  -- number
    print(0x1p+16)        -- 65536
    print(type(0x3p-2))   -- number
    print(0x3p-2)         -- 0.75

    16진수 또한 실수 표기가 가능하며, p혹은 P를 붙여 지수부와 가수부로 나누어 표기할 수 있습니다.

     

    4. string

     

    문자열을 표현하는 타입입니다.

    한 글자당 8비트로 표현되며, 0을 포함한 수치 코드를 쓸 수 있습니다.

    문자열은 여러 기능을 포함하고 있습니다.

    더보기

    문자열은 수정할 수 없는 immutable 값 입니다.

    생성된 문자열은 수정이 불가하며 수정해야 할 경우 수정된 새 문자열을 만들어야 합니다.

    foo = "one string"
    bar = string.gsub(foo, "one", "another")
    print(foo)  -- one string
    print(bar)  -- another string

    위 예제는 string.gsub함수로 문자열을 수정하는 함수입니다.

     

    문자열의 길이는 #연산자를 변수 앞에 사용하여 얻을 수 있습니다.

    foo = "one string"
    print(#foo)            -- 10
    print(#"hello world!") -- 12

     

    두 문자열을 합칠 때에 ..연산자를 사용할 수 있습니다.

    foo = "one"         -- one
    bar = foo.."two"    -- onetwo

     

    문자열은 큰따옴표, 작은따옴표 모두 사용할 수 있습니다.

    foo = "a 'line'"        -- a 'line'
    bar = 'another "line"'  -- another "line"

    사용하지 않은 따옴표는 문자열 안에서 이스케이프 문자 없이 사용할 수 있습니다.

    이스케이프 문자는 C와 동일하게 사용할 수 있습니다.

     

    이스케이프 문자를 통해 글자를 명시할 수 있습니다.

    print('\104\101ll\x6f') -- hello
    print('he\108\x6co')    -- hello

    위 두 print는 같은 결과를 출력합니다.

    이스케이프에 세 자리 십진수나 16진수로 문자를 표현한 예제입니다. 

    예제의 경우 hello의 l에 십진수 \108과 \x6c등을 사용했습니다.

     

    Lua는 구간 문자열을 지원합니다.

    foo = [=[
    function bar()
        print("function bar")
    end
    ]=]
    print(foo)
    
    --[==[
    function bar()
        print("function bar")
    end
    ]==]

    위 foo의 출력은 아래 --[==[로 시작되는 주석과 같은 결과를 출력합니다.

    구간 문자열은 문자열을 [[와 ]]로 감싸서 사용할 수 있습니다.

    또한, 구간 문자열 내부에 [[혹은 ]]가 있을 경우, 대괄호 사이에 임의의 =기호를 추가할 수 있습니다.

    위 예제가 그 경우를 표시한 예제로, foo는 =를 한번, 주석은 =를 두번 사용했습니다.

    =를 사용한 구간 문자열 혹은 주석의 경우, 서로 같은 갯수의 =기호를 사용해서 열고 닫아야 합니다.

     

    문자열에 수치 연산을 적용할 경우, Lua는 해당 문자열에 대해 숫자로의 변환을 시도합니다.

    print("10" + 1)    -- 11
    print("10 + 1")    -- 10 + 1
    print("hello" + 1) -- Error

    반대로, 문자열 연산에 실수 값이 존재할 경우 실수에 대한 문자열로의 변환을 시도합니다.

    print(10.12 .. 20) -- 10.1220

    해당 자동 변환이 항상 작동하는 것은 아닙니다.

    if 10 == "10" then
        print("true")
    else
        print("false")
    end

    해당 코드의 결과는 false입니다.

     

    명시적인 변환의 경우, tonumber 혹은 tostring 함수를 사용합니다.

    해당 함수는 각각 인자를 number혹은 string으로의 변환을 시도하며, 실패할 경우 nil을 반환합니다.

    if tostring(10) == "10" then
        print("true")
    else
        print("false")
    end

    해당 코드의 결과는 true입니다.

     

    5. function

     

    함수를 표현하는 타입입니다.

    Lua의 함수는 1급 객체로, 함수를 변수에 저장하거나, 다른 함수의 인자로 전달하거나, 반환할 수 있습니다.

    더보기

    함수를 변수에 저장하는 예제입니다.

    function foo(arg)
        print(arg)
    end
    
    a = foo
    a("hello world!")  -- hello world!

     

    함수를 다른 함수의 인자로 전달하는 예제입니다.

    function foo(arg)
        print("Func foo")
        print(arg)
    end
    
    function bar(argFunc)
        print("Func bar")
        argFunc("HELLO WORLD!")
    end
    
    bar(foo)
    --[[
    Func bar
    Func foo
    HELLO WORLD!
    ]]

     

    함수를 반환하는 예제입니다.

    function foo(arg)
        print("Func foo")
        return function() print(arg) end
    end
    
    a = foo
    b = a("Hello")
    print("----")
    b()

     

    6. table

     

    table은 인덱스를 이용해 참조할 수 있는 배열입니다.

    인덱스는 nil을 제외한 모든 값을 사용할 수 있습니다.

    더보기

    테이블의 생성은 {}로 감싸지는 표현식을 통해 가능합니다.

    foo = { a = 1 }
    foo.b = 12
    bar = 'b'
    foo['c'] = 123
    print(foo.a)    -- 1
    print(foo[bar]) -- 12
    print(foo["c"]) -- 123
    print(foo['d']) -- nil

    테이블의 생성, 할당과 관련된 예제입니다.

    .과 []를 사용해 테이블의 필드를 참조했는데, 두 방법 모두 인터프리터의 관점에서는 동일합니다.

     

    Lua를 배열과 같이 사용할 경우, 인덱스는 1부터 사용되는 것이 관례입니다.

    특정 기능들은 해당 관례에 맞춰 구현되어 있습니다.

    foo = {}
    foo[1] = 'a'
    foo[2] = 'b'
    foo[3] = 'c'
    foo[5] = 'e'
    print(#foo)  -- 3

    #연산자는 테이블에도 사용할 수 있습니다.

    이 경우, 1부터 연속된 인덱스의 갯수를 반환합니다.

    위 foo[5]를 제외할 경우, 테이블 foo는 빈 곳 (nil)이 없는 테이블이라 볼 수 있습니다.

    이와 같이 중간에 비어있는 인덱스가 없는 테이블을 순열(Sequence)이라고 합니다.

     

    7. thread

     

    타입 이름은 thread이지만, Lua에서는 코루틴(Coroutine)이라는 표현을 사용합니다.

    제어의 한 줄기로써 사용되지만, 멀티 프로세싱과는 달리 한 번에 한 코루틴만 수행됩니다.

    자세한 내용은 다른 글에서 작성할 수 있도록 하겠습니다.

     

    8. userdata

     

    userdata 타입은 C데이터를 Lua에 저장하기 위해 사용됩니다.

    C로 작성된 응용 프로그램이나 라이브러리에서 정의한 새로운 타입을 표현하기 위해 사용됩니다.

    자세한 내용은 다른 글에서 작성할 수 있도록 하겠습니다.

     


     

    기본 타입들에 대하여 알아보았습니다.

    그 중 thread와 userdata는 이후 글에서 자세히 다룰 수 있도록 하겠습니다.

     

    감사합니다.

    댓글

Designed by Tistory.