Khi nào thì một bao đóng triển khai Fn, FnMut và FnOnce?


114

Là gì điều kiện cụ thể cho một đóng cửa để thực hiện Fn, FnMutFnOnceđặc điểm?

Đó là:

  • Khi nào thì một bao đóng không thực hiện FnOnceđặc điểm?
  • Khi nào thì một bao đóng không thực hiện FnMutđặc điểm?
  • Khi nào thì một bao đóng không thực hiện Fnđặc điểm?

Ví dụ, thay đổi trạng thái của bao đóng trên phần thân của nó khiến trình biên dịch không thực thi Fntrên nó.


11
Bạn đã xem bài báo tuyệt vời gần đây về việc đóng cửa chưa?
Shepmaster

Câu trả lời:


126

Mỗi đặc điểm đại diện cho các thuộc tính ngày càng hạn chế hơn về các bao đóng / hàm, được biểu thị bằng các chữ ký của call_...phương thức của chúng , và đặc biệt là kiểu self:

  • FnOnce( self) là các hàm có thể được gọi một lần
  • FnMut( &mut self) là các hàm có thể được gọi nếu chúng có &mutquyền truy cập vào môi trường của chúng
  • Fn( &self) là các hàm có thể được gọi nếu chúng chỉ có &quyền truy cập vào môi trường của chúng

Một quá trình đóng |...| ...sẽ tự động triển khai nhiều nhất có thể.

  • Tất cả các bao đóng đều triển khai FnOnce: một bao đóng không thể được gọi một lần sẽ không xứng đáng với tên. Lưu ý rằng nếu một bao đóng chỉ thực hiện FnOnce, nó chỉ có thể được gọi một lần.
  • Các đóng cửa không di chuyển ra khỏi triển khai chụp của chúng FnMut, cho phép chúng được gọi nhiều lần (nếu có quyền truy cập không định hướng vào đối tượng hàm).
  • Các cửa sổ đóng cửa không cần quyền truy cập duy nhất / có thể thay đổi đối với triển khai chụp của chúng Fn, cho phép chúng được gọi về cơ bản ở mọi nơi.

Những hạn chế này theo sau trực tiếp từ loại selfvà "gỡ bỏ" các đóng thành cấu trúc; được mô tả trong bài đăng trên blog của tôi Tìm kiếm Đóng cửa trong Rust .

Để biết thông tin về việc đóng cửa, hãy xem Đóng cửa: Các hàm ẩn danh có thể nắm bắt môi trường của chúng bằng ngôn ngữ lập trình Rust .


Nếu một bao đóng chỉ thực hiện FnOnce, điều này có nghĩa là nó chỉ có thể được gọi một lần?
nalply

@nalply, vâng, chỉ một lần.
huon

9
Tôi đã đọc nhầm bình luận của nalply và nó khiến tôi bối rối. Các độc giả trong tương lai, xin lưu ý rằng ông đã nói "nếu việc đóng cửa chỉ thực hiện FnOnce".
sleeparrow

2
Chi tiết triển khai: sẽ tự động triển khai nhiều nhất có thể. không hoàn toàn đúng, nó sẽ tự động triển khai chúng nếu có vẻ cần thiết. Bạn có thể phát hiện thiếu Fn-impl cho một bao đóng được sử dụng cho đối số FnMut bằng cách sử dụng chuyên môn hóa. Đây là lỗi github.com/rust-lang/rust/issues/26085
bluss
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.