5 Hàm


Các hàm là cơ chế chính để trừu tượng hóa các câu lệnh và biểu thức trong Lua. Các hàm vừa có thể thực hiện một tác vụ cụ thể (đôi khi được gọi là thủ tục hoặc chương trình con trong các ngôn ngữ khác) hoặc tính toán và trả về giá trị. Trong trường hợp đầu tiên, chúng tôi sử dụng một lệnh gọi hàm như một câu lệnh; trong trường hợp thứ hai, chúng tôi sử dụng nó như một biểu thức:

    print(8*9, 9/8)
    a = math.sin(3) + math.cos(10)
    print(os.date())

Trong cả hai trường hợp, chúng tôi viết một danh sách các đối số được đặt trong dấu ngoặc đơn. Nếu lời gọi hàm không có đối số, chúng ta phải viết một danh sách trống () để chỉ ra lệnh gọi. Có một trường hợp đặc biệt đối với quy tắc này: Nếu hàm có một đối số duy nhất và đối số này là một chuỗi ký tự hoặc một hàm tạo bảng, thì các dấu ngoặc đơn là tùy chọn:

    print "Hello World"     <-->     print("Hello World")
    dofile 'a.lua'          <-->     dofile ('a.lua')
    print [[a multi-line    <-->     print([[a multi-line
     message]]                        message]])
    f{x=10, y=20}           <-->     f({x=10, y=20})
    type{}                  <-->     type({})

Lua cũng cung cấp một cú pháp đặc biệt cho các cuộc gọi hướng đối tượng, toán tử dấu hai chấm. Một biểu thức như o: foo (x) chỉ là một cách khác để viết o.foo (o, x), nghĩa là, để gọi o.foo thêm o làm đối số bổ sung đầu tiên. Trong Chương 16, chúng ta sẽ thảo luận chi tiết hơn về các lệnh gọi như vậy (và lập trình hướng đối tượng).

Các chức năng được sử dụng bởi chương trình Lua có thể được định nghĩa cả trong Lua và C (hoặc bằng bất kỳ ngôn ngữ nào khác được ứng dụng chủ sử dụng). Ví dụ, tất cả các hàm thư viện được viết bằng C; nhưng thực tế này không liên quan đến các lập trình viên Lua. Khi gọi một hàm, không có sự khác biệt giữa các hàm được định nghĩa trong Lua và các hàm được định nghĩa trong C.

Như chúng ta đã thấy trong các ví dụ khác, một định nghĩa hàm có một cú pháp thông thường; ví dụ

-- add all elements of array `a'
    function add (a)
      local sum = 0
      for i,v in ipairs(a) do
        sum = sum + v
      end
      return sum
    end

Trong cú pháp đó, định nghĩa hàm có tên (thêm, trong ví dụ trước), danh sách các tham số và phần thân, là danh sách các câu lệnh.

Các tham số hoạt động chính xác như các biến cục bộ, được khởi tạo với các đối số thực tế được đưa ra trong lời gọi hàm. Bạn có thể gọi một hàm với một số đối số khác với số tham số của nó. Lua điều chỉnh số lượng đối số thành số lượng tham số, như nó thực hiện trong một phép gán nhiều: Các đối số bổ sung bị loại bỏ; tham số phụ nhận được nil. Ví dụ, nếu chúng ta có một hàm như

function f(a, b) return a or b end

chúng ta sẽ có ánh xạ sau từ đối số thành tham số:

    CALL             PARAMETERS
       
    f(3)             a=3, b=nil
    f(3, 4)          a=3, b=4
    f(3, 4, 5)       a=3, b=4   (5 is discarded)

Mặc dù hành vi này có thể dẫn đến lỗi lập trình (dễ phát hiện khi chạy), nhưng nó cũng hữu ích, đặc biệt là đối với các đối số mặc định. Ví dụ, hãy xem xét hàm sau để tăng bộ đếm toàn cục.

function incCount (n)
      n = n or 1
      count = count + n
    end

Hàm này có 1 là đối số mặc định của nó; nghĩa là, lệnh gọi incCount (), không có đối số, số gia đếm từng một. Khi bạn gọi incCount (), Lua đầu tiên khởi tạo n bằng nil; hoặc kết quả trong toán hạng thứ hai của nó; và kết quả là Lua gán giá trị mặc định 1 cho n.

Leave a comment