일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- lua install
- 엑스퍼트생일축하해
- QTcpServer
- C API
- 수도권주택공급
- lua setup
- FILE TRANSFER
- meta table
- #신혼부부 #결혼준비 #신혼부부희망타운신혼부부특별공급
- lua for windows
- 등록임대주택
- 청량리역한양수자인192
- file read
- Lua
- 월세
- 프리미어 영상변환
- TCP/IP
- C++ API
- 국토교통부
- lua interpreter
- 프리미어 영상저장
- 엑스퍼트2주년
- file write
- 중소규모택지
- #부동산전자거래 #부동산전자계약 #부동산계약 #부동산전자계약방법 #부동산전자계약하는법 #부동산계약방법 #부동산중개수수료 #부동산중개수수료아끼기 #부동산복비아끼기
- 찾다죽는줄
- 티몬삼겹살데이
- QT TCP
- object
- file open
- Today
- Total
Value Creator의 IT(프로그래밍 / 전자제품)
#2 Lua 모든 문법 핵심 요약 본문
--[[1. 주석처리
한 줄 주석(짝대기 2개)
--
여러줄 주석 시작
--[[
여러줄 주석 끝
--]]
num = 42 -- 모든 수는 double 형(최대 52bit)
s = 'walternate' -- 파이썬(Python) 같은 바꿀 수 없는 문자열.
t = "쌍 따옴표는 문자열(string)"
u = [[ 이중 대괄호는
여러 줄 문자열의
시작과 끝을 나타냅니다.]]
t = nil -- t를 정의되지 않은 변수로 만듭니다. 루아에는 가비지 컬렉션 기능이 있습니다.
-- 블록은 do와 end로 표기됩니다.
while num < 50 do
num = num + 1 -- ‘++’ 또는 ’+=’ 연산자는 없습니다.
end
-- If 절:
if num > 40 then
print('over 40')
elseif s ~= 'walternate' then -- ‘~=’는 같지 않음을 뜻합니다.
-- 파이썬 같이 같음을 확인하는 연산자는 ‘==’입니다. ‘==’는 문자열에도 사용될 수 있습니다.
io.write('not over 40\n') -- 기본적으로 stdout으로 출력됩니다.
else
-- 변수들은 기본적으로 전역(global) 변수로 만들어집니다.
thisIsGlobal = 5 -- 변수 이름을 표기할 때는 낙타 등 표기법이 흔히 사용됩니다.
-- 변수를 지역(local) 변수로 만드는 방법:
local line = io.read() -- 다음 stdin 줄을 읽습니다.
-- ‘..’ 연산자를 사용하여 문자열 잇기:
print('Winter is coming, ' .. line) -- Winter is coming + ‘stdin으로 입력한 문자열’ 출력.
end
-- 정의되지 않은 변수들은 nil을 리턴합니다.
-- 이것은 에러가 아닙니다:
foo = anUnknownVariable -- foo에 anUnknownVariable(한 정의되지 않은 변수)를 넣습니다. 이제 foo = nil.
aBoolValue = false
-- 불(boolean) 연산에서는 오직 nil과 false만 거짓입니다. 0 과 '' 는 참입니다!
if not aBoolValue then print('twas false') end
-- 'or'와 'and'는 short-circuit 됩니다.
-- 다음은 C/자바스크립트에서의 a?b:c 연산자와 비슷합니다.
ans = aBoolValue and 'yes' or 'no' --> 'no'
karlSum = 0
for i = 1, 100 do -- 그 범위의 양 끝을 포함합니다.
karlSum = karlSum + i
end
-- "100, 1, -1"를 쓰면 범위를 감소하도록 정할 수 있습니다.
fredSum = 0
for j = 100, 1, -1 do
fredSum = fredSum + j
end
-- 일반적으로, 범위는 시작, 끝[, 증가 또는 감소량] 입니다.
-- 또 다른 루프 작성법:
repeat
print('the way of the future')
num = num - 1
until num == 0
----------------------------------------------------
-- 2. 함수.
----------------------------------------------------
function fib(n) -- 피보나치 수
if n < 2 then return 1 end
return fib(n - 2) + fib(n - 1) -- 재귀 함수
end
-- 함수 안에 정의된 함수(closure)와 이름 없는 함수도 쓸 수 있습니다.
function adder(x) -- 리턴되는 함수는 adder가 호출될 때 생성됩니다. 그리고 x의 값을 기억합니다.
return function (y) return x + y end
end
a1 = adder(9) -- adder가 처음 호출되었으므로 a1에 9가 들어갑니다.
a2 = adder(36) -- adder가 처음 호출되었으므로 a2에 36이 들어갑니다.
print(a1(16)) -- a1에는 9가 들어있습니다.
-- 거기서 다시 a1 인스턴스 adder를 호출하였으므로, 9+16=25가 출력됩니다.
print(a2(64)) -- a2에는 36이 들어있습니다.
-- 거기서 다시 a2 인스턴스 adder를 호출하였으므로, 36+64=100이 출력됩니다.
-- 리턴, 함수 호출, 그리고 할당은 모두 리스트로 동작합니다. 그 리스트의 길이는 다를 수도 있습니다.
-- 매치되지 않는 수신자들은 nil로 취급됩니다. 매치되지 않는 전송자들은 버려집니다.
x, y, z = 1, 2, 3, 4
-- x = 1, y = 2, z = 3입니다. 4 는 버려집니다.
function bar(a, b, c)
print(a, b, c)
return 4, 8, 15, 16, 23, 42
end
x, y = bar('zaphod') --> "zaphod nil nil"이 출력됩니다.
-- x = 4, y = 8이 할당됩니다. 값 15, 16, 23, 42 는 버려집니다.
-- 함수는 first-class입니다, 함수는 지역 또는 전역일 수 있습니다.
-- 다음 두 줄은 같습니다:
function f(x) return x * x end
f = function (x) return x * x end
-- 그리고 다음 두 줄도 같습니다:
local function g(x) return math.sin(x) end
local g; g = function (x) return math.sin(x) end
-- 'local g' 선언은 g를 자기 참조 가능하게 만듭니다.
-- 삼각 함수들은 라디안으로 동작합니다.
-- 매개변수에 한 문자열만 들어갈 때는 (함수를 호출할 때) 괄호를 붙이지 않아도 됩니다.:
print 'hello' -- 잘 동작합니다.
----------------------------------------------------
-- 3. 테이블.
----------------------------------------------------
-- 테이블은 루아의 유일한 합성 자료 구조입니다.
-- 테이블은 연관 배열(associative arrays)입니다.
-- php 배열 또는 자바스크립트 객체와 비슷합니다.
-- 테이블은 리스트로도 사용될 수 있는 해시 참조 사전입니다.
-- 테이블을 사전이나 맵(map)으로 사용하기.
-- 사전은 기본적으로 문자열 키(key)를 가집니다.
t = {key1 = 'value1', key2 = false}
-- 문자열 키는 자바스크립트 같은 점 표기를 쓸 수 있습니다.
print(t.key1) -- 'value1' 출력.
t.newKey = {} -- 새로운 key/value 쌍 추가.
t.key2 = nil -- 테이블 t에서 key2 제거.
-- 키로 (nil이 아닌) 임의의 표기를 사용할 수도 있습니다.
u = {['@!#'] = 'qbert', [{}] = 1729, [6.28] = 'tau'}
print(u[6.28]) -- "tau" 출력
-- 키 매칭은 기본적으로 숫자와 문자열 값으로 수행됩니다.
-- 그러나 테이블은 동질성(identity)에 의해 수행됩니다.
a = u['@!#'] -- a = 'qbert'
b = u[{}] -- 1729가 들어갈 것으로 기대했지만, 실제로 들어가는 값은 nil입니다. b = nil.
-- 이유는 검색이 실패하기 때문입니다.
-- 검색 실패 이유는 우리가 사용한 키가 원래 값을 저장할 때 사용된 것과 같은 객체가 아니기 때문입니다.
-- 그래서 더 이식성 높은 키는 문자열과 숫자입니다.
-- 매개변수가 테이블 하나인 함수 호출에서는 괄호가 필요 없습니다.
function h(x) print(x.key1) end
h{key1 = 'Sonmi~451'} -- 'Sonmi~451' 출력.
for key, val in pairs(u) do -- 테이블 반복.
print(key, val)
end
-- _G 는 모든 전역들(globals)을 위한 특별한 테이블입니다.
print(_G['_G'] == _G) -- 'true' 출력.
-- 테이블을 리스트 또는 배열로 사용하기.
-- 리스트는 암묵적으로 정수형 키를 설정합니다.
v = {'value1', 'value2', 1.21, 'gigawatts'}
for i = 1, #v do -- #v 는 리스트 v의 크기(size)입니다.
print(v[i]) -- 인덱스는 1부터 시작합니다.
end
-- 리스트는 실제 타입이 아닙니다. v는 그저 하나의 테이블입니다.
-- 이 테이블은 연속적인 정수 키를 가지며, 리스트로 취급됩니다.
----------------------------------------------------
-- 3.1 메타테이블과 메타메소드
----------------------------------------------------
-- 테이블 하나는 메타테이블 하나를 가질 수 있습니다.
-- 그 메타테이블은 연산자 오버로딩을 제공합니다.
-- 나중에 우리는 어떻게 메타테이블이 자바스크립트의 프로토타입 동작을 지원하는지 볼 것입니다.
f1 = {a = 1, b = 2} -- 분수 a/b를 표현.
f2 = {a = 2, b = 3}
-- 이것은 실패할 것입니다. (분수에 대한 덧셈은 루아에 정의되어 있지 않기 때문입니다.)
-- s = f1 + f2
metafraction = {}
function metafraction.__add(f1, f2)
sum = {}
sum.b = f1.b * f2.b
sum.a = f1.a * f2.b + f2.a * f1.b
return sum
end
setmetatable(f1, metafraction)
setmetatable(f2, metafraction)
s = f1 + f2 -- f1의 메타테이블에 있는 __add(f1,f2)를 호출합니다.
-- f1, f2는 자바스크립트의 프로토타입과 달리 메타테이블에 키가 없습니다.
-- 그래서 당신은 반드시 그 키들을 getmetatable(f1)과 같이 다시 받아와야 합니다.
-- 그 메타테이블은 루아가 그것에 대해 아는 키를 가진 보통 테이블입니다. __add 같이요.
-- 그러나 다음 줄은 실패합니다. 왜냐하면, s에는 메타테이블이 없기 때문입니다.
-- t = s + s
-- 아래 주어진 클래스 같은 패턴들이 이 문제를 해결합니다.
-- 메타테이블에서 __index는 (myFavs.animal에 있는 점 처럼) 점 참조를 오버로드합니다.
defaultFavs = {animal = 'gru', food = 'donuts'}
myFavs = {food = 'pizza'}
setmetatable(myFavs, {__index = defaultFavs})
eatenBy = myFavs.animal -- 동작합니다! 메타테이블, 고마워요.
-- 직접적 테이블 검색이 실패하면, (검색은) 그 메타테이블의 __index 값을 사용하여 다시 시도됩니다.
-- 그리고 이것이 반복됩니다.
-- 한 __index 값은 또한 더 사용자가 원하는 대로 맞춰진(customized) 검색을 위한 함수(테이블, 키)일 수 있습니다.
-- (add 같은) __index의 값들은 메타메소드라 불립니다.
-- 메타메소드의 전체 목록입니다. 여기서 a는 메타메소드를 가진 한 테이블입니다.
-- __add(a, b) for a + b
-- __sub(a, b) for a - b
-- __mul(a, b) for a * b
-- __div(a, b) for a / b
-- __mod(a, b) for a % b
-- __pow(a, b) for a ^ b
-- __unm(a) for -a
-- __concat(a, b) for a .. b
-- __len(a) for #a
-- __eq(a, b) for a == b
-- __lt(a, b) for a < b
-- __le(a, b) for a <= b
-- __index(a, b) <함수 또는 테이블> for a.b
-- __newindex(a, b, c) for a.b = c
-- __call(a, ...) for a(...)
----------------------------------------------------
-- 3.2 클래스 같은 테이블 그리고 상속.
----------------------------------------------------
-- 클래스는 (루아에) 내장되어 있지 않습니다. 클래스는 테이블과 메타테이블을 사용하여 만들어집니다.
-- 그 예제와 설명은 아래와 같습니다.
Dog = {} -- 1. |
----------------------------------------------------
-- 상속 예제:
LoudDog = Dog:new() -- 1. -- LoudDog에 ‘new’ 키가 없기 때문입니다. -- 그래서 seymour.key는 seymour.key, LoudDog.key, Dog.key 중 -- 주어진 키를 가진 첫번 째 테이블일 것입니다. |
-- 만약 필요하면, 하위 클래스의 new()는 기본 클래스의 것처럼 만들 수 있습니다.
function LoudDog:new()
newObj = {}
-- newObj 설정
self.__index = self
return setmetatable(newObj, self)
end
----------------------------------------------------
-- 4. 모듈.
----------------------------------------------------
--[[ 저는 이 스크립트의 나머지 부분이 실행 가능한 상태로 남도록
-- 이 절(section)을 주석으로 처리하고 있습니다.
-- mod.lua 파일이 다음과 같다고 가정합시다.
local M = {} |
-- 다른 파일도 mod.lua 파일에 있는 기능을 사용할 수 있습니다.
local mod = require('mod') -- mod.lua 파일 실행.
-- require는 모듈을 포함(include)하게 하는 표준 방법입니다.
-- require는 이렇게 동작합니다. (만약 캐쉬되지 않으면요. '캐쉬되다'의 뜻은 아래에서 다시 설명됩니다.)
local mod = (function ()
<mod.lua 파일의 내용>
end)()
-- mod.lua는 한 함수에 들어있는 내용처럼 한 지역 변수 mod에 대입됩니다.
-- 그래서 mod.lua 안에 있는 지역 변수와 지역 함수들은 그 함수 밖에서는 보이지 않게됩니다.
-- mod는 mod.lua의 M과 같기 때문에, 다음은 동작합니다.
mod.sayHello() -- Hrunkner에게 안녕이라고 말합니다.
-- 지역 함수인 sayMyName은 오직 mod.lua 안에서만 존재하므로, 다음은 틀렸습니다.
mod.sayMyName() -- 에러
-- require의 리턴 값들은 캐쉬되어 require가 여러 번 호출되더라도 한 파일은 한번만 실행됩니다.
-- 예를 들어, mod2.lua가 "print('Hi!')”를 포함한다고 가정합시다.
local a = require('mod2') -- Hi! 출력
local b = require('mod2') -- 출력 안함; a=b.
-- dofile은 require와 비슷하지만 캐싱을 하지 않습니다.
dofile('mod2.lua') --> Hi!
dofile('mod2.lua') --> Hi! (다시 실행합니다.)
-- loadfile은 루아 파일을 로드하지만 아직 실행하지는 않습니다.
f = loadfile('mod2.lua') -- mod2.lua를 실행하기 위해서는 f()를 호출해야 합니다.
-- loadstring은 문자열을 위한 loadfile입니다.
g = loadstring('print(343)') -- 한 함수를 리턴합니다.
g() -- 343을 출력합니다; 이 함수가 호출되기 전까지는 아무것도 출력되지 않습니다.
--]]
----------------------------------------------------
-- 5. 참고 자료
----------------------------------------------------
lua-users.org에 있는 Lua short reference를 확인해보는 것도 도움이 될 수 있습니다.
여기서 다루지 않은 주요 주제들은 표준 라이브러리들입니다:
* string library
* table library
* math library
* io library
* os library
어쨌든, 이 문서 파일 전체는 하나의 유효한 루아 파일입니다. 이 문서를 learn.lua로 저장하고 “lua learn.lua”로 실행해 보십시오!
이 글은 tylerneylon.com을 위해 처음 쓰였습니다.
'1. 프로그래밍 > 2) LUA' 카테고리의 다른 글
#6 [lua 1.1] 개요 - Lua 내부 코드 읽어보기 (0) | 2019.08.21 |
---|---|
#5. [LUA] Lua 설치하기(Lua For Windows) (0) | 2019.04.19 |
#4. [LUA] C 또는 C++ 과 Lua script연동 (0) | 2019.04.18 |
#3 Lua Tutorial ( File 열기, 쓰기 / 파일호출 / table 및 metatable) (0) | 2019.04.17 |
#1 Lua 프로그래밍 Chap 0. Lua Development Tools 활용(특징 : Eclipse 기반, 자동 완성기능) (0) | 2019.03.19 |