[Lua Script] 2장 타입과 값

seb Incode·2022년 7월 11일
0

Lua Script

목록 보기
1/1
post-thumbnail

변수 타입

루아 스크립트는 동적 언어로, 변수를 선언할 때 변수 타입을 지정하지 않는다.

변수 타입 종류로는

  • nil
  • boolean
  • number
  • string
  • userdata
  • function
  • thread
  • table

8가지가 있다.

마지막 print()의 경우, type()는 항상 string 값을 리턴하기 때문에 "string"이 출력된다.



변수 a에 여러 타입의 값을 대입한 예제이다.
변수를 선언할 때 값을 지정하지 않으면 nil값으로 초기화된다.

nil

루아에서는 변수가 현재 값이 없는 상태를 나타내는 값으로 nil을 사용한다.

boolean

참, 거짓을 표현하는 타입으로 true, false값을 가진다.
그런데 루아에서는 boolean 타입 값 뿐만 아니라 다른 값으로도 참, 거짓을 나타낼 수 있다.
조건문에서 nil 값도 false로 판별하고, 그 외의 모든 값은 true로 판별한다.
0과 빈 문자열도 true로 판별하니 주의하자

실수

... 실수나 정수 둘다 number 타입이다 정도까지만 훑고 넘어가자

문자열

말 그대로 문자들의 순열이다.
루아에서는 문자열을 수정할 수 없다.
다른 언어의 경우 부분 문자열을 수정할 수 있지만, 루아는 바꿀 수 없다.
그 대신 수정하길 원하는 내용으로 새 문자열을 만들어서 쓸 수는 있다.

a = "one string"
b = string.gsub(a, "one", "another")	-- 문자열 a의 "one" -> "another"로 바꿔달라
print(a)
print(b)

velog는 루아스크립트를 지원하지 않는듯해서,, java로 처리함 ㅠ

a = "Hello"
print(#a)  --변수 값의 길이 구하기
a = 358
-- print(#a)  -- a 값이 문자열이 아니라서 에러남

"#" 연산자를 활용해서 문자열의 길이를 구할 수 있다.
단, 값이 문자열일 때만 가능하다.

루아도 이스케이프 문자가 있다.

print("one line\nnext line\n\"in quotes\", 'in quotes'")
print("a backlash inside quotes: \'\\\'")
print("a simpler way: '\\'")

구간 문자열

구간 주석을 썼을 때처럼 대괄호 두 개로 감싸서 문자열 상수를 구분할 수 있다.
이렇게 대괄호로 표현된 문자열은 여러 줄로 작성될 수 있고, 이스케이프 문자도 해석하지 않는다.
아래 예제처럼 코드의 일부분을 문자열로 담을 때 편리하다.

page = [[
<html>
<head>
  <title>An HTML Page</title>
</head>
<body>
  <a href="http://www.lua.org">Lua</a>
</body>
</html>

]]

print(page)

만약 구간 문자열 내에 [[ 나 ]] 가 문자열 자체로 포함되어 있는 경우가 있다.
이럴 때는 [==[ 이런식으로 = 기호를 넣어주면 된다.

page = [==[
<html>
<head>
  <title>An HTML Page</title>
</head>
<body>
  <a href="http://www.lua.org">Lua</a>
</body>
</html>

]==]	-- "=" 개수 안맞춰주면 에러남

print(page)

강제 변환

타입이 서로 다른 값들끼리 연산을 하는 경우, 한 쪽 타입으로 강제 변환하여 연산하는데,
루아는 문자열에 수치 연산을 적용하면 숫자로의 변환을 시도한다.

print("10"+1)  --수치로써 연산 후 결과 값 출력
print("10 +1")  -- 단순 문자열 출력
print("-5.3e-10"*"2")  --수치로써 연산 후 결과 값 출력
-- print("hello"+1)  -- 에러 남

반대로 문자열이 필요한 곳에 실수 값이 있으면 실수 값을 문자열로 변환한다.

print(10 .. 20)

루아에서 ".."는 문자열을 이어 붙이는 연산자이다.
숫자와 이 연산자를 이어 붙이면 소수점으로 오해하므로 공백을 줘야 한다 ❕

하지만 강제 변환은 비추...하고
명시적 변환을 꼭 해주자

a = "15468000"  --문자열
print(tonumber(a)+1)  --명시적 변환 후 연산

tonumber()

  • 문자열을 실수로 변환하는 함수
  • 문자열이 실수가 아닌 경우 nil 리턴

tostring()

  • 실수를 문자열로 변환하는 함수

tostring() 외에 10 .. "" 이런식으로 실수와 빈 문자열을 연결하면 문자열로 변환된다.

테이블

루아에서 배열, 리스트, 레코드, 객체를 테이블이라고 한다.
배열의 인덱스로 nil를 제외한 모든 값(실수, 문자열 등등)을 사용할 수 있다.
따라서 array[x] != array["x"] 인 셈이다.

arr = {}  -- 테이블 생성 및 'arr'로 참조
k = "x"
arr[k] = 10  --인덱스 키가 "x"이고 값이 10인 원소 저장
arr[20] = "great"  --인덱스 키가 20이고 값이 "great"인 원소 저장
print(arr["x"])  -- 10 출력
k = 20
print(arr[k])  -- "great" 출력
arr["x"] = arr["x"] + 1  -- 10+1
print(arr["x"])  -- 11 출력
arr = {}  -- 테이블 생성 및 'arr'로 참조
arr["x"] = 10
b = arr  -- 변수 'arr''b'는 이제 같은 테이블을 참조함
print(b["x"])  -- 10 출력
b["x"]  = 20
print(arr["x"])  -- 20 출력
arr = nil  -- 변수 arr는 더 이상 테이블을 참조 X, b만 참조
b = nil  -- 테이블을 참조하는 변수 모두 사라짐, 테이블은 알아서 삭제됨

테이블을 참조하는 변수가 사라지면, 루아의 가비지 콜렉터에 의해 테이블이 삭제된다.

a = {}  -- 빈 테이블

--  원소 1000개 추가
for i =1, 1000 do a[i] = i*2 end
print(a[9])  -- 18 출력
a["x"] = 10
print(a["x"])  -- 10 출력
print(a["y"])  -- nil 출력

위 예제는 원소를 추가하지 않은 인덱스에 접근하면 어떻게 되는지를 확인함을 위해서다.
a["y"] 라는 원소를 추가한 적이 없기 때문에 nil이 출력된다.

루아에서는 a.name과 a["name"]은 같은 문법을 의미한다.
단, a[name]는 아니다. 매우 다른 것..

a = {}
a.x = 10
print(a.x)  -- 10 출력
print(a["x"])  -- 10 출력
a = {}
x = "y"
a[x] = 10
print(a[x])  -- 10 출력
print(a.x) -- nil 출력
print(a.y) -- 10 출력

밑 예제가 더 어려운 케이스다.
변수 x냐, 문자열 "x"냐 이걸 제대로 구분하지 않으면 헷갈릴듯..

일반적으로 배열 인덱스는 정수를 넣는다.
하지만 루아는 인덱스 키로 1, "+1", "1" 모두 가능하고 엄연히 서로 다른 것으로 간주한다.
인간의 경우는 그렇지 않기 때문에 실수가 발생할 수 있으므로 명시적 변환을 통해 실수를 방지하자.

아래 예제 참고 !

i = 10; j = "10"; k="+10"
a = {}
a[i] = "one value"
a[j] = "another value"
a[k] = "yet another value"
print(a[i]) -- "one value" 출력
print(a[j])  --"another value" 출력
print(a[k])  -- "yet another value" 출력

print(a[tonumber(j)])  -- "one value" 출력
print(a[tonumber(k)])  -- "one value" 출력

함수

루아에서의 함수는 1급 값이다.
즉,

  • 함수를 변수에 저장
  • 다른 함수의 인자로 넘겨주기
  • 함수를 반환 받기

이런 기능을 제공한다.

일단 여기까지만 짚고 넘어가자

유저데이터와 스레드

유저데이터

C 데이터를 루아 변수에 저장하는 데 유저데이터 타입을 사용한다.
여기까지만 짚고 넘어가자...

스레드는 완전 뒤에서....

0개의 댓글