2011-05-20 40 views
17

Làm cách nào để gọi một hàm cần được gọi từ phía trên quá trình tạo của nó? Tôi đã đọc điều gì đó về các khai báo chuyển tiếp, nhưng Google không hữu ích trong trường hợp này. Cú pháp chính xác cho điều này là gì?Chuyển tiếp định nghĩa một hàm trong Lua?

Cảm ơn.

Trả lời

29

Lua là một ngôn ngữ động và chức năng chỉ là một loại giá trị có thể được gọi với toán tử (). Vì vậy, bạn không thực sự cần phải chuyển tiếp khai báo hàm này nhiều như đảm bảo rằng biến trong phạm vi khi bạn gọi nó là biến mà bạn nghĩ nó là.

Đây không phải là vấn đề ở tất cả các biến toàn cầu chứa hàm, vì môi trường toàn cầu là nơi mặc định để xem xét để giải quyết tên biến. Tuy nhiên, đối với các hàm cục bộ, bạn cần đảm bảo rằng biến cục bộ đã nằm trong phạm vi từ điểm mà bạn cần gọi giá trị nó lưu trữ, và cũng đảm bảo rằng trong thời gian chạy nó thực sự đang giữ một giá trị có thể được gọi .

Ví dụ, đây là một cặp chức năng địa phương lẫn nhau đệ quy:

local a,b 
a = function() return b() end 
b = function() return a() end 

Tất nhiên, đó cũng là một ví dụ của việc sử dụng đuôi cuộc gọi cho phép đệ quy vô hạn mà không làm gì, nhưng điểm ở đây là khai báo. Bằng cách khai báo các biến với local trước khi có một hàm được lưu trữ trong nó, các tên đó được biết là các biến cục bộ trong phạm vi từ vựng của phần còn lại của ví dụ. Sau đó, hai hàm được lưu trữ, mỗi hàm đề cập đến biến khác.

+1

Ok, cảm ơn. Tôi đã tự tìm ra nó, nhưng câu trả lời này rất hữu ích. –

9

Bạn có thể chuyển tiếp khai báo một hàm bằng cách tuyên bố tên của nó trước khi tuyên bố các cơ quan chức năng thực tế:

local func1 
local func2 = function() 
    func1() 
end 
func1 = function() 
    --do something 
end 

Tuy nhiên về phía trước tờ khai là chỉ cần thiết khi tuyên bố chức năng với phạm vi địa phương. Đó thường là những gì bạn muốn làm, nhưng Lua cũng hỗ trợ một cú pháp giống như C, trong trường hợp tờ khai phía trước là không cần thiết:

function func2() 
    func1() 
end 
function func1() 
    --do something 
end 
+4

Trên thực tế, ví dụ đầu tiên của bạn không làm những gì bạn nghĩ từ 'local func1' đang khai báo một biến * new * của tên đó và để nguyên 'func1' mồ côi đầu tiên và vẫn được đặt thành' nil'. – RBerteig

+0

oops điểm tốt, tôi sẽ sửa chữa rằng – jhocking

+1

Ví dụ thứ hai của bạn là xấu, quá, bởi vì ngây thơ gọi "func2" từ bên dưới func1 sẽ làm việc, nhưng không phải vì bất kỳ loại "chuyển tiếp". Thay vào đó, func1 được khai báo trong môi trường toàn cục (_G), và khi func2 tra cứu func1, nó sẽ kiểm tra _G. Điều đó có nghĩa là func1 được khai báo trước khi func2 được chạy và do đó khi nó kiểm tra _G, nó hoạt động. Ném một cuộc gọi func2 ngay lập tức sau khi func2 được xác định là kết quả trong một lỗi ... vì func1 không được khai báo/xác định. – LuaWeaver

0

kiểm tra dưới lua nhúng trong FreeSWITCH, tờ khai phía trước không hoạt động:

fmsg("CRIT", "It worked.") 
function fmsg(infotype, msg) 
    freeswitch.consoleLog(infotype, msg .. "\n") 
end 

kết quả:

[ERR] mod_lua.cpp: 203 /usr/local/freeswitch/scripts/foo.lua:1: cố gắng gọi toàn cầu 'fmsg' (một giá trị nil)

Đảo ngược thứ tự làm việc (duh).

0

Không hoạt động cho tôi nếu tôi cố gắng gọi hàm trước khi định nghĩa. Tôi đang sử dụng kịch bản Lua này trong nginx conf. Đoạn

lua entry thread aborted: runtime error: lua_redirect.lua:109: attempt to call global 'throwErrorIfAny' (a nil value)

Mã -

... 
throwErrorIfAny() 
... 

function throwErrorIfAny() 
    ngx.say("request not allowed") 
    ngx.exit(ngx.HTTP_OK) 
end 

Với một số câu trả lời khác cũng đã chỉ ra rằng nó đã không làm việc cho họ, hoặc, có thể là tờ khai chuyển tiếp của Lua không làm việc với các công cụ khác .

PS: Nó hoạt động tốt nếu tôi đặt định nghĩa chức năng trước và sau đó gọi nó sau khi phường.

Các vấn đề liên quan