Pin
- Kiểu
Pin và khái niệm pinning là những thành phần nền tảng của hệ sinh thái bất đồng bộ trong Rust
- Tuy nhiên,
Pin là một trong những yếu tố khó tiếp cận và dễ bị hiểu sai
- Bài viết này giải thích
Pin muốn đạt được điều gì, nó hình thành như thế nào, và những vấn đề hiện tại của Pin là gì
Requirements
- Để hỗ trợ tham chiếu trong hàm bất đồng bộ, cần phải lưu tham chiếu bên trong
Future
- Vấn đề là các tham chiếu này có thể là tự tham chiếu
- Mã ví dụ:
async fn foo<'a>(z: &'a mut i32) { ... }
async fn bar(x: i32, y: i32) -> i32 {
let mut z = x + y;
foo(&mut z).await;
z
}
- Trạng thái nội bộ của
Bar như sau:
enum Bar {
Start { x: i32, y: i32 },
FirstAwait { z: i32, foo: Foo<'?> },
Complete,
}
- Mục tiêu của
Pin là thao tác với các kiểu tự tham chiếu một cách an toàn
Non-solutions: move constructors and offset pointers
- Constructor di chuyển và con trỏ offset không hoạt động trong Rust
- Constructor di chuyển sẽ sửa con trỏ khi di chuyển, nhưng điều đó là không thể trong Rust
- Con trỏ offset không hoạt động vì tại thời điểm biên dịch không thể biết một tham chiếu có phải là tự tham chiếu hay không
The “pinned typestate”
- Đối tượng không phải là luôn luôn không thể di chuyển, mà phải trở nên không thể di chuyển từ một thời điểm nhất định
- Trong mô hình của Ralf Jung, đối tượng chuyển từ trạng thái "được sở hữu" sang trạng thái "được chia sẻ", rồi sang trạng thái "được cố định"
- Khi đã vào trạng thái cố định, đối tượng không thể di chuyển nữa
?Move
- Trước
Pin, đã có nỗ lực thử một giải pháp dựa trên trait mới tên là Move
- Kiểu không triển khai
Move sẽ chuyển sang trạng thái cố định khi lấy tham chiếu
- Tuy nhiên,
Move không cung cấp khả năng tương thích ngược
Pin
Pin thiết kế một kiểu tham chiếu mới để đưa đối tượng vào trạng thái cố định
Pin được triển khai như một API thư viện nên vẫn giữ được tính tương thích ngược
- Bằng cách thêm auto trait
Unpin, phần lớn các kiểu không cần phân biệt giữa trạng thái cố định và trạng thái thông thường
The problems with Pin
Pin có nhiều vấn đề về mặt tính dễ sử dụng
- Vì
Pin được triển khai như một kiểu thư viện, nhiều tính năng vốn có của kiểu tham chiếu thông thường đã bị mất đi
- Ví dụ,
&mut T không triển khai Copy nhưng vẫn có thể được truyền làm đối số nhiều lần
Pin không cung cấp sự tiện lợi này
- Rất nhiều nhầm lẫn phát sinh khi sử dụng
Pin
In my next post…
Pin giúp các hàm bất đồng bộ có thể được biên dịch an toàn với các tham chiếu tùy ý
- Tuy nhiên,
Pin làm tăng độ phức tạp, và bài viết tiếp theo sẽ bàn về cách cải thiện điều này
Tóm tắt của GN⁺
Pin là một thành phần quan trọng của hệ sinh thái bất đồng bộ Rust
- Vấn đề về tính dễ sử dụng của
Pin xuất phát từ việc nó được triển khai như một kiểu thư viện
- Bài viết tiếp theo sẽ bàn về các cách cải thiện
Pin
- Một dự án có chức năng tương tự là
pin-project-lite
1 bình luận
Ý kiến Hacker News
Lý do
Pinkhó hiểu là vì tài liệu chính thức không giải thích rõ ràngPinđảm bảo đối tượng tuyệt đối không bị di chuyển", nhưng thực tế không phải vậyUnpin, nênPinthường không có tác dụng gìTmàPinthực sự có tác dụng là rất đặc biệt và tài liệu không nhấn mạnh đủ điều nàyPinkhó là vì bản thân nó không có ý nghĩa gì riêngPin, ngôn ngữ hay thư viện chuẩn không cho biếtPincó thể và không thể làm gìInnerTypesẽ tạo thêm các phương thức và API bổ sung (không an toàn ở mức nội bộ) để có thể thao tác với đối tượng đã được pinPinlà cung cấp một con trỏ có ít "chức năng nội tại" hơnNên thêm "rust" vào tiêu đề thì mới biết bài viết nói về gì
Thuật ngữ "value identity" không được định nghĩa ở bất kỳ đâu trong tài liệu của Mojo
Pinlà một ví dụ điển hình về cái tên chính xác về mặt kỹ thuật nhưng khó hiểuDropmang nghĩa quen thuộc hơn, còn "pinning" thì không như vậyimmovable!(…)sẽ tốt hơn, nhưng cũng khó nghĩ ra tên nào hay hơnprevent_moving!(…)cùng với traitPreventMovecó thể sẽ tốt hơnNếu một ngôn ngữ tương tự Rust có move-constructor thì nhu cầu với
Pincó thể biến mấtCó thể di chuyển đối tượng qua tham chiếu
&mutbằngmem::swap/replace, nhưng trên thực tế hiếm khi thật sự cầnswapvàreplacethành không an toàn có thể giải quyết được vấn đềWithoutBoats đang có các cuộc thảo luận rất sôi nổi về chủ đề async iterator,
poll,pinPinning/
!Movehữu ích cho nhiều mục đích ngoài async/await