Introduction
: 함수는 숫자나 문자열처럼 전역이나 지역변수에 또는 테이블에 넣을 수 있고, 함수에 인자로 전달이 가능하며, 다른 함수로부터 반환 받을 수도 있다.
함수는 이름이 없다.
??? 무슨말인가 하면, 우리가 알고 있는 함수의 이름은 사실 그 함수 주소값을 담고 있는 변수의 이름이다.
a = {p = print}
a.p("Hello world") --> Hello World
print = math.sin -- print는 이제 sin 함수를 참조
a.p(print(1)) --> 0.841470
sin = a.p -- sin은 이제 print 함수를 참조
sin(10, 20) --> 10 20
그렇다 사실
function foo (x) return 2*x end 문장은
foo = function (x) return 2*x end 를 보기좋게 썻던 것 뿐이다.
1. 클로저
: 클로저는 익명함수 + 비지역 변수 이다.
익명함수는 알겠는데 비지역 변수는 무엇?
function newCounter()
local i = 0
return function () -- 익명 함수
i = i + 1
return i
end
end
c1 = newCounter()
print(c1()) --> 1
print(c1()) --> 2
위 코드에서 c1이 참조하고 있는 익명함수가 호출되는 시점에는 newCounter() 호출이 끝난 상태이기 때문에 지역변수 i의 생명주기가 끝나 버린다. 그런데 어떻게 c1이 참조하고 있는 익명함수에서 지역변수 i를 사용할 수 있는거지?
그것은 블럭이라는 존재 때문이다. 블럭은 익명함수와 위 코드에서 지역변수 i의 값을 저장해서 가지고 있는 놈이라고 보면 된다.
그럼 아래를 보자.
c2 = newCounter()
print(c2()) --> 1
print(c1()) --> 3
print(c2()) --> 2
c1과 c2는 서로 다른 블럭이기 때문에 위와같이 서로다른 인스턴스처럼 동작한다.
사실 루아에서 우리가 함수라 부르며 호출하는 것들은 함수가 아니라 클로저 이다.
클로저는 콜백 함수를 구현할 때도 유용하다. 예를들어, 계산기를 만들때 0~9 까지 유사한 버튼을 만들어야 하는데 이런 버튼을 다음과 같은 함수로 만들어 낼 수 있다.
function digitButton (digit)
reutrn Button { label = tostring(digit),
action = function ()
addToDisplay(digit)
end
}
end
다음은 테이블에 함수를 저장하는 특별한 문법을 소개하겠다. 일반적인 값을 테이블에 넣을 때 사용하는 문법을 써도 되지만, 다음과 같이 사용해도 된다.
Lib = {}
function Lib.foo (x, y) return x + y end
function Lib.goo (x, y) return x - y end
'Lua Script' 카테고리의 다른 글
[Lua] 메타테이블과 메타메서드 (0) | 2018.03.28 |
---|---|
[Lua] 반복자 (0) | 2018.03.28 |
[Lua] 함수 (0) | 2018.03.27 |
[Lua] 문장 (0) | 2018.03.27 |
[Lua] 표현식 (0) | 2018.03.27 |