Điều này hiện được đề cập đến trong ấn bản thứ hai của Ngôn ngữ lập trình Rust . Tuy nhiên, chúng ta hãy đi sâu vào một chút bổ sung.
Hãy để chúng tôi bắt đầu với một ví dụ đơn giản hơn.
Sử dụng phương pháp tính trạng khi nào là thích hợp?
Có nhiều cách để cung cấp ràng buộc muộn :
trait MyTrait {
fn hello_word(&self) -> String;
}
Hoặc là:
struct MyTrait<T> {
t: T,
hello_world: fn(&T) -> String,
}
impl<T> MyTrait<T> {
fn new(t: T, hello_world: fn(&T) -> String) -> MyTrait<T>;
fn hello_world(&self) -> String {
(self.hello_world)(self.t)
}
}
Bỏ qua bất kỳ chiến lược triển khai / hiệu suất nào, cả hai đoạn trích trên đều cho phép người dùng chỉ định một cách năng động cách thức hello_worldhoạt động.
Một sự khác biệt (ngữ nghĩa) là traitbảo đảm thực hiện rằng đối với một loại nhất định Tthực hiện trait, hello_worldsẽ luôn luôn có hành vi tương tự trong khi structthực hiện phép có hành vi khác nhau trên cơ sở mỗi ví dụ.
Việc sử dụng một phương pháp có phù hợp hay không phụ thuộc vào usecase!
Khi nào thì thích hợp để sử dụng kiểu liên kết?
Tương tự như các traitphương thức ở trên, một kiểu liên kết là một dạng ràng buộc muộn (mặc dù nó xảy ra khi biên dịch), cho phép người dùng traitchỉ định kiểu thay thế cho một phiên bản nhất định. Đó không phải là cách duy nhất (vì vậy câu hỏi):
trait MyTrait {
type Return;
fn hello_world(&self) -> Self::Return;
}
Hoặc là:
trait MyTrait<Return> {
fn hello_world(&Self) -> Return;
}
Tương đương với ràng buộc muộn của các phương pháp ở trên:
- cái đầu tiên thực thi rằng đối với một cái nhất định
Selfcó một cái Returnliên kết
- thứ hai, thay vào đó, cho phép thực hiện
MyTraitcho Selfcho nhiềuReturn
Hình thức nào phù hợp hơn tùy thuộc vào việc nó có hợp lý để thực thi unicity hay không. Ví dụ:
Deref sử dụng một kiểu được liên kết bởi vì nếu không có unicity, trình biên dịch sẽ phát điên khi suy luận
Add sử dụng kiểu được liên kết bởi vì tác giả của nó nghĩ rằng với hai đối số sẽ có kiểu trả về logic
Như bạn có thể thấy, mặc dù Dereflà một usecase rõ ràng (hạn chế kỹ thuật), trường hợp của Addnó ít rõ ràng hơn: có lẽ nó sẽ có ý nghĩa nếu i32 + i32nhường một trong hai i32hoặc Complex<i32>tùy thuộc vào ngữ cảnh? Tuy nhiên, tác giả đã thực hiện phán đoán của họ và quyết định rằng việc nạp chồng kiểu trả về cho các phép bổ sung là không cần thiết.
Lập trường cá nhân của tôi là không có câu trả lời đúng. Tuy nhiên, ngoài đối số unicity, tôi sẽ đề cập rằng các kiểu liên kết làm cho việc sử dụng đặc điểm dễ dàng hơn vì chúng giảm số lượng các tham số phải được chỉ định, vì vậy trong trường hợp lợi ích của sự linh hoạt của việc sử dụng một tham số đặc điểm thông thường không rõ ràng, tôi đề xuất bắt đầu với một loại liên kết.
trait/struct MyTrait/MyStructcho phép chính xác mộtimpl MyTrait forhoặcimpl MyStruct.trait MyTrait<Return>cho phép nhiềuimpls vì nó chung chung.Returncó thể là bất kỳ loại nào. Cấu trúc chung giống nhau.