Đ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_world
hoạt động.
Một sự khác biệt (ngữ nghĩa) là trait
bảo đảm thực hiện rằng đối với một loại nhất định T
thực hiện trait
, hello_world
sẽ luôn luôn có hành vi tương tự trong khi struct
thự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 trait
phươ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 trait
chỉ đị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
Self
có một cái Return
liên kết
- thứ hai, thay vào đó, cho phép thực hiện
MyTrait
cho Self
cho 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ù Deref
là một usecase rõ ràng (hạn chế kỹ thuật), trường hợp của Add
nó ít rõ ràng hơn: có lẽ nó sẽ có ý nghĩa nếu i32 + i32
nhường một trong hai i32
hoặ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/MyStruct
cho phép chính xác mộtimpl MyTrait for
hoặcimpl MyStruct
.trait MyTrait<Return>
cho phép nhiềuimpl
s vì nó chung chung.Return
có thể là bất kỳ loại nào. Cấu trúc chung giống nhau.