2012-07-08 2 views
3

루아의 문자열에서 (of x) 함수를 만들고 있습니다. 내가 사용하는 코드는문자열에서 루아 함수를 만듭니다.

function fcreate(fs) 
return assert(loadstring("return function (x) return " .. fs.." end"))() 
end 

입니다.

u=fcreate("math.sin(x)") 

올바른 일을합니다.

그러나 로컬 변수를 좋아하지 않는 것 같습니다. 따라서

local c=1 
u=fcreate("math.sin(x)+c") 

은 c가 로컬이므로 작동하지 않습니다.

이 수정 가능합니까?

+0

처럼 보이도록 그렇게 할 수

return (function(a,b,c) return function(x) return print(a, x) end end)(...) 

처럼 보이게하기 위해 폐쇄를 구축 할 수 있습니다 왜 downvote? –

답변

13

"loadstring does not compile with lexical scoping" 아니요, 아니요, loadstring 통화 외부의 지역 주민을 볼 수 없습니다.


이 고칠 수 있나요?

다릅니다. 왜 처음에로드 스트링을 사용하고 있습니까? 루아는 퍼스트 클래스 값으로 클로저를 지원하므로, 여러분의 예제에서 왜 이 필요합니까?로드 스트링.

귀하의 예 :

u = fcreate("math.sin(x)+c") 

loadstring 또는 fcreate 기능을 위해 필요없이 다시 쓸 수 있습니다 :

물론과 동일
u = function(x) return math.sin(x)+c end 

:

function u(x) return math.sin(x) + c end 

I 사용자가있는 경우 loadstring의 사례를 볼 수 있습니다. 당신이 다른 기능으로 컴파일하고 싶었던 상상할 수없는 표현이지만, 로컬 c을 가진 당신의 경우는 그렇지 않다는 것을 암시합니다. 집에서 구운 람다 구문을 좀 만들려고하십니까?

+8

당신의 코드가 원하는 방식으로 작동하지 않는 이유에 대한 루아의 저자 자신의 설명과 연결시켜주는 첫 번째 줄에 * 질문 *에 답했습니다. 그런 다음, 제가 좋고 도움이되고 싶기 때문에, 저는 * 문제 * (두 섹션을 분리하는 수평선 규칙에 유의하십시오)를 해결하려고했습니다. 후자의 섹션은 주로 문제의 컨텍스트/요구 사항이 명시되지 않았기 때문에 추측으로 구성되어 있으므로 몇 가지 추가 정보를 게시하고 요구 사항을 명확히하여 요청하면 도움이 될 것입니다. 나를 downvote 보람 주셔서 감사합니다. – Mud

2

합리적인 방법으로 수행 할 수 없습니다. 이유의 예를 들어, 이것 좀 봐 :

function makefunction(name) 
    local a = 1 
    local b = 2 
    local c = 3 
    -- ... 
    return assert(loadstring("return " .. name)) 
end 

local a = 4 
local func = makefunction("a") 
print(func()) 

를이 무엇을 인쇄, 일 경우? 1 또는 4? 함수가 더 이상 존재하지 않더라도 함수가로드 된 위치에서 변수를 캡처합니까? 또는 그것이 불린 곳에서 그것을 찾으십니까?

첫 번째는 함수가 어딘가에서 어휘 적으로 범위가 지정된다는 것을 의미합니다. 함수가 종료 된 후에 변수에 액세스 할 수 있다는 것은 변수가 동적으로 상위 값으로 승격되어야한다는 것을 의미합니다. 이는 루아가 현재 할 수있는 것이 아닙니다. 현재 루아는 컴파일 중에 로컬 변수에 대한 모든 액세스를 볼 수 있기 때문에 어떤 변수가 업적 (성능 적중)과 로컬로 유지 될지를 안다.

두 번째는 loadstring 함수 내의 변수 액세스가 루아에서 다른 모든 액세스와 완전히 다르게 작동 함을 의미합니다. 루아는 동적 범위 지정이 아닌 어휘 범위 지정을 사용합니다. 그것은 Lua에서 거대한 구현 변경이 될 것이고, 매우 일관성이없는 변경이 될 것입니다.

어느 쪽도 지원되지 않습니다. 은 Lua 5.1에서 setfenv 또는 env 매개 변수 load(...)을 사용하여 동적으로로드 된 함수의 환경을 제어하지만 둘 다 로컬 변수에 자동으로 액세스 할 수 없습니다.

1

로컬 변수를 변경할 필요가없는 경우 생성 된 함수에 해당 값을 인수로 전달하는 것입니다. 닫을 변수는 수동으로 지정해야하지만 그다지 좋지는 않습니다.

예를 들어, 우리는 당신의 기능을 변경하여

function fcreate(variables, fs) 

    local varnames = {} 
    local varvalues = {} 
    local nvars = 0 
    for n,v in pairs(variables) do 
    nvars = nvars + 1 
    table.insert(varnames, n) 
    table.insert(varvalues, v) 
    end 

    local chunk_str = (
    'return (function(' .. table.concat(varnames, ',') .. ') ' .. 
     'return function(x) return ' .. fs .. ' end ' .. 
     'end)(...)' 
) 

    return assert(loadstring(chunk_str))(unpack(varvalues, 1, nvars)) 

end 

local a = 1; 
local f = fcreate({a=a}, 'x+a') 
print(f(1), f(2)) 
관련 문제