《루아프로그래밍》 독서노트 제6장: 깊이 함수

9270 단어
Lua에서 함수는 특정한 어법 영역을 가진 첫 번째 클래스 값입니다.'어법역'은 무슨 뜻입니까?이것은 한 함수가 다른 함수에 끼워 넣을 수 있고 내부의 함수가 외부 함수에 접근할 수 있는 변수를 가리킨다.Lua에서 헷갈리기 쉬운 개념은 함수가 다른 모든 값과 마찬가지로 익명이라는 것이다. 즉, 함수는 이름이 없다는 것이다.하나의 함수 이름을 토론할 때, 실제로는 어떤 함수를 가진 변수를 토론한다.함수 정의는 실제적으로 하나의 표현식입니다:function foo(x)return 2*x end 그 실제는foo=function(x)return 2*x end, 사실은 부수문입니다.표현식 "function(x) < body > end"를 함수의 구조식으로 볼 수 있으며, 구조식의 결과를 익명 함수라고 부른다.한 함수는 다른 함수의 매개 변수로 하고 다른 함수를 실참으로 받아들이는 함수를 고급 함수라고 한다.
    network = {{name = "grauna", IP="210.26.30.34"}
               {name = "lua", IP = "210.26.23.12"}}
    table.sort(network, function(a, b) return (a.name > b.name) end)  -->           

6.1 closure (클립 함수)


한 함수를 다른 함수에 쓰면, 내부에 있는 함수는 외부 함수의 국부 변수에 접근할 수 있으며, 이 특징을 '문법역' 이라고 부른다.왜 Lua에서 이런 접근을 허용합니까?그 이유는 함수가 '제1류 값' 이기 때문이다.다음 코드를 참조하십시오.
function newCounter()
    local i = 0
    return function()
        i = i + 1
        return i
    end
end
local c1= newCounter()
c1()    -->1
c1()    -->2

간단하게 말하자면, 하나의closure는 하나의 함수에 이 함수가 접근하는 모든 '비국부 변수' 를 더한 것이다.newCounter를 다시 호출하면 새 closure를 생성합니다.
local c2 = newCounter()
print(c2()) -->1
print(c1()) -->3

기술적으로 볼 때 Lua에는 closure만 있고 함수는 특수한 closure일 뿐이다.closure는 미리 설정된 함수를 재정의하는 등 자주 사용하는 사용법도 있습니다.
oldSin = math.sin
math.sin = function(x)
    return oldSin(x*math.pi . 180)
end

같은 기술로 안전한 운행 환경, 즉 이른바'모래함'을 만들 수 있다.
do
    local oldOpen = io.open
    local access_OK = function(filename, mode)
    <          >
    end
    io.open = function(filename, mode)
        if access_Ok(filename, mode) then
            return oldOpen(filename, mode)
        else
            return nil, "access denied"
        end
    end
end

6.2 비전역 함수


Lua에서 함수는 일반적으로 글로벌 변수가 아닌 하나의 테이블에 저장됩니다.
    Lib1 = {}
    Lib1.foo = function(x, y) return x + y end
    Lib2 = {foo = function(x,y) return x + y end}

또한 Lua는 이러한 함수를 정의하는 또 다른 구문을 제공합니다.
    Lib = {}
    function Lib.foo(x,y) return x+y end

이런 국부 함수의 정의에 대해 Lua는 특수한'문법 설탕'도 지원한다.
local function foo(<    >)
    
end

또한 귀속의 국부 함수를 정의할 때 주의해야 할 점이 있다.다음 코드를 보십시오.
local fact = function(n)
    if n == 0 then return 1
    else return n*fact(n-1)
    end
end

이렇게 정의된 오류의 관건은 오른쪽의 표현식을 계산한 다음에 왼쪽 변수를 정의하는 데 있다.fact(n-1)를 호출할 때fact 변수는 아직 정의가 끝나지 않았기 때문에 실제적으로 전체적인fact를 호출하는 것이지 그 자체가 아니다.올바른 쓰기 방법은 다음과 같습니다. 먼저 로컬 변수 fact를 정의해야 합니다.
local fact
fact = function(n)
    if n==0 then return 1
    else return n * fact(n -1)
    end
end

Lua는 local function foo end의 정의 방식에 대해
local foo
foo = function()  end

그래서 이런 방식으로 귀속 함수를 정의하면 오류가 없을 것이다.물론, 이 기교는 간접적으로 귀속되는 함수에 대해서는 무효이며, 명확한 선행 성명을 사용해야 한다.
    local f,g
    function g()
        f()
    end
    function f()          -->     local function,        f       
        g()
    end

6.3 정확한 꼬리 호출


Lua는 "Tail-Call Replication"을 지원합니다.이른바 '꼬리 호출' 은 고토와 유사한 함수 호출이다.한 함수가 호출될 때 다른 함수의 마지막 동작이 호출될 때, 이 호출이야말로 '꼬리 호출' 이라고 할 수 있다.
function f(x) return g(x) end

상기 호출에서 f가 g를 호출한 후에 할 일이 없기 때문에 프로그램은 함수 f의 창고 정보를 보존할 필요가 없기 때문에 꼬리 호출을 할 때 어떠한 창고 공간도 소모하지 않는다. 이런 실현은 바로'꼬리 호출 제거'다."꼬리 호출"은 창고 공간을 소모하지 않기 때문에 한 프로그램은 무수한 끼워 넣은 "꼬리 호출"을 가질 수 있다.
function foo(n)
    if n > 0 then return foo(n-1) end
end

Lua에서 '꼬리 호출' 의 가장 큰 응용 프로그램은 '상태기' 를 작성하는 것이다.이런 프로그램은 하나의 함수로 하나의 상태를 표시한다.

좋은 웹페이지 즐겨찾기