2011-11-15 65 views
6

Tôi đang học Lua và đã bắt gặp khái niệm về các chức năng ẩn danh. Đó là thú vị nhưng tôi đã tự hỏi những lợi thế bổ sung nó cung cấp trên các chức năng không vô danh.Các chức năng Chưa xác định và Ẩn danh Lua

Vì vậy, Nếu tôi có một cái gì đó giống như

function(a,b) return (a+b) end 

Chức năng là ẩn danh và nếu tôi có

function add(a,b) return (a+b) end 

Chức năng là không nặc danh. Thứ hai là tốt hơn bởi vì tôi có thể gọi nó bất cứ nơi nào tôi muốn và tôi cũng biết những gì chức năng của tôi đang làm. Vậy lợi thế của các chức năng ẩn danh là gì? Am i thiếu cái gì ở đây?

+7

Bạn đã nhận nó ngược. Một mô hình tinh thần hữu ích hơn nhiều đang xử lý 'hàm f (...) ... end' như là cú pháp cho' local f = function (...) ... end', và nghĩ về các hàm nói chung là các đối tượng thay thế các khối xây dựng tĩnh của chương trình của bạn. Bạn không hỏi tại sao bạn có thể sử dụng chữ số mà không cho họ một tên tiếng Anh phức tạp trước tiên, phải không? – delnan

Trả lời

20

Thành thật mà nói, không có chức năng như có tên là ở Lua. Tất cả các hàm thực sự ẩn danh, nhưng có thể được lưu trữ trong các biến (có tên).

Hàm có tên cú pháp function add(a,b) return a+b end thực sự là syntactic sugar cho add = function(a,b) return a+b end.

Chức năng thường được sử dụng như xử lý sự kiện và cho các quyết định mà một thư viện không/có thể không biết, ví dụ nổi tiếng nhất là table.sort() - sử dụng chức năng của bạn, bạn có thể xác định thứ tự sắp xếp:

people = {{name="John", age=20}, {name="Ann", age=25}} 
table.sort(people, function (a,b) return a.name < b.name end) 

Điểm có lẽ bạn sẽ không cần chức năng này sau. Tất nhiên, bạn cũng có thể lưu các chức năng cho một biến (có thể là địa phương) và sử dụng rằng:

local nameComparator = function (a,b) return a.name < b.name end 
table.sort(people, nameComparator) 

Để biết thêm thông tin, đọc section on functions in PiL này.

4

Ví dụ thứ hai là tương đương với
add = function(a,b) return a+b end
Vì vậy, thực sự bạn đang sử dụng chức năng ẩn danh tất cả các thời gian, trong một cảm giác tầm thường.

Nhưng các chức năng ẩn danh có thể hữu ích hơn nhiều trong các ngữ cảnh khác. Ví dụ, sử dụng chức năng để biến đổi các chức năng khác (linh hồn của lập trình chức năng.)

function make_version_with_n_args (func, n) 
    if n == 1 then 
     return function (x) return x end 
    else 
     return function (x, ...) 
      return func (x, make_version_with_n_args (func, n-1)(...)) 
     end 
    end 
end 

add_four = make_version_with_n_args (function (a, b) return a+b end, 4) 

print (add_four(3, 3, 3, 3)) 

add_sizes = {} 
for i = 1, 5 do 
    add_sizes[i] = make_version_with_n_args(function (a, b) return a+b end, i) 
end 

func_args = {} 
for i = 1, 5 do 
    func_args[#func_args+1] = 2 
    print (add_sizes[i](unpack(func_args))) 
end 

function make_general_version (func) 
    return function (...) 
     local args = {...} 
     local result = args[#args] 
     for i = #args-1,1,-1 do 
      result = func(args[i], result) 
     end 
     return result 
    end 
end 

general_add = make_general_version (function (a, b) return a+b end) 

print (general_add(4, 4, 4, 4)) 

Về cơ bản, bạn có thể tạo một tên cho mỗi chức năng duy nhất nếu bạn muốn, nhưng trong tình huống mà bạn đang ném xung quanh rất nhiều chức năng một lần, nó là thuận tiện hơn để không làm như vậy.

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