[Lua] 함수의 내부

Lua Script 2018. 3. 28. 20:28

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
Posted by 홍성곤
,