2012-11-16 29 views
6

Mục đích của việc chuyển đối số cho lua_resume và lua_yield là gì?Lua: lua_resume và lua_yield mục đích đối số

Tôi hiểu rằng trong lần gọi đầu tiên tới lua_resume, các đối số được chuyển đến hàm lua đang được tiếp tục. Điều này thật ý nghĩa. Tuy nhiên tôi hy vọng rằng tất cả các cuộc gọi tiếp theo để lua_resume sẽ "cập nhật" các đối số trong hàm của coroutine. Tuy nhiên đó không phải là trường hợp.

Mục đích của việc chuyển đối số cho lua_resume cho lua_yield là gì? Có thể hàm lua chạy dưới coroutine có quyền truy cập vào các đối số được truyền bởi lua_resume không?

Trả lời

10

Điều Nicol nói. Bạn vẫn có thể duy trì các giá trị từ các resume cuộc gọi đầu tiên nếu bạn muốn:

do 
    local firstcall 
    function willyield(a) 
    firstcall = a 
    while a do 
     print(a, firstcall) 
     a = coroutine.yield() 
    end 
    end 
end 

local coro = coroutine.create(willyield) 
coroutine.resume(coro, 1) 
coroutine.resume(coro, 10) 
coroutine.resume(coro, 100) 
coroutine.resume(coro) 

sẽ in

1 1 
10 1 
100 1 
+0

Tôi cảm thấy như thế này không trả lời được câu hỏi.OP là về/C API/hàm lua_resume() và lua_yield(), có ngữ nghĩa khác với thư viện chuẩn 'coroutine.resume()', v.v. (Ví dụ, lua_resume lấy ba đối số - hai trong số đó là lua_State ...) – BadZen

+0

Tôi nghĩ rằng nó trả lời câu hỏi về mục đích chuyển các tham số và cung cấp một ví dụ dễ dàng để thử có một thông dịch viên Lua. Trong thực tế, OP cho biết nhiều trong bình luận của mình theo câu trả lời của Nicol. Bạn luôn có thể cung cấp câu trả lời của riêng mình nếu bạn nghĩ mình có câu trả lời hay hơn. –

+0

Có một sự khác biệt lớn giữa đối tượng coroutine trong libs (ví dụ như đóng gói một lua_State) và sử dụng API C. Tôi không có câu trả lời hay hơn, vì vậy tôi đã mở một câu hỏi khác hỏi cụ thể về API C. Câu trả lời của Nichol và của bạn ở đây đều nói về đối tượng thư viện coroutine. Có khoảng 100 dòng mã thực hiện điều đó theo API lua_ *. Nó không rõ ràng, và tài liệu ngắn gọn về chi tiết. – BadZen

5

Lua không thể đưa ra các đối số ban đầu giá trị mới một cách kỳ diệu. Họ có thể không còn ở trên ngăn xếp nữa, tùy thuộc vào việc tối ưu hóa. Hơn nữa, không có dấu hiệu cho thấy mã khi nó mang lại, vì vậy nó có thể không thể nhìn thấy những đối số nữa. Ví dụ, nếu coroutine được gọi là một hàm, hàm mới đó không thể thấy các đối số được truyền vào hàm cũ.

coroutine.yield() trả về các đối số được chuyển đến cuộc gọi resume tiếp tục coroutine, để trang web của lệnh gọi năng suất có thể xử lý các tham số theo ý muốn. Nó cho phép mã thực hiện việc nối lại để giao tiếp với mã cụ thể làm việc sinh lợi. yield() chuyển các đối số của nó dưới dạng giá trị trả lại từ resumeresume chuyển đối số của nó dưới dạng giá trị trả lại cho yield. Điều này thiết lập một con đường giao tiếp.

Bạn không thể làm điều đó theo bất kỳ cách nào khác. Chắc chắn không phải bằng cách sửa đổi các đối số có thể không hiển thị trên trang web yield. Nó đơn giản, thanh lịch và có ý nghĩa.

Ngoài ra, nó được coi là cực kỳ thô lỗ để đi chọc vào giá trị của một ai đó. Đặc biệt là một chức năng đã hoạt động. Hãy nhớ rằng: các đối số chỉ là các biến cục bộ chứa đầy các giá trị. Người dùng không nên mong đợi nội dung của các biến đó thay đổi trừ khi nó thay đổi chính nó. Tuy nhiên, chúng là các biến số local. Chúng chỉ có thể được thay đổi cục bộ; do đó tên.

+0

Cảm ơn! Vì vậy, để làm rõ, một khi một coroutine được bắt đầu các giá trị địa phương không thể được sửa đổi bên ngoài? Tôi cho rằng tôi cần phải giao tiếp với các bên trong của coroutine bằng các biến toàn cầu sau đó? Ví dụ: tôi có thể đếm số "đối tượng lân cận" trong trò chơi, trong đó coroutine cần biết có bao nhiêu đối tượng khác nằm trong khoảng cách xa. Để làm được điều này, tôi phải có toàn cầu để lưu trữ số lượng vật thể lân cận? Tôi đã hy vọng tôi có thể coi trọng coroutine ngay trước khi tôi tiếp tục để tránh cluterring không gian tên với globals. – RandyGaul

+0

Các giá trị có thể được sửa đổi; bạn chỉ cần gán kết quả của coroutine.yield() gọi tới cùng một biến mà bạn truyền vào như là tham số ban đầu. Nhìn vào câu trả lời của tôi cho ví dụ. –

+0

@RandyGaul: "* một khi coroutine được khởi động, các giá trị cục bộ không thể được sửa đổi bên ngoài *" biến 'cục bộ' không thể sửa đổi bên ngoài * dấu chấm *; coroutines không phải là đặc biệt. Nếu bạn muốn chuyển số này, hãy chuyển chúng thành các tham số để 'tiếp tục' và thu thập chúng như là giá trị trả về từ' yield'. Như tôi đã nói, đó là giao diện truyền thông mà bạn có. –