2015-09-24 19 views
5

Trong Rust, tôi có xu hướng có vấn đề về thiết kế khi viết mô-đun với các đặc điểm. Tôi không luôn luôn chắc chắn cho dù tôi muốn:Sự khác biệt giữa phương thức Trait mặc định và chức năng tham số là gì?

pub trait Foo { 
    fn foo(&self) -> bool; 

    fn bar(&self) { 
     if self.foo() { 
      // Do something! 
     } else { 
      // Do something else! 
     } 
    } 
} 

Hoặc

pub trait Foo { 
    fn foo(&self) -> bool; 
} 

pub fn bar<T>(fooer: &T) where T: Foo { 
    if fooer.foo() { 
     // Do something! 
    } else { 
     // Do something else! 
    } 
} 

(Tất nhiên, ví dụ thực tế có thể có những đặc điểm phức tạp hơn hoặc chữ ký chức năng)

Trong khi các vấn đề về thiết kế vượt ra ngoài phạm vi của Stack Overflow, tôi không hoàn toàn chắc chắn rằng tôi thậm chí hiểu được sự khác biệt có ý nghĩa, khách quan giữa hai, và tôi không cảm thấy như duyệt thư viện chuẩn đã giảm nhiều ánh sáng. Nó dường như như thư viện chuẩn của Rust thích sử dụng variable.method() thay vì mod::function(&variable) trong hầu hết các trường hợp. Tuy nhiên, điều đó vẫn không thực sự trả lời câu hỏi vì đó chỉ là một đối số hướng dẫn phong cách thay vì dựa trên kiến ​​thức khách quan về sự khác biệt.

Khác với sự khác biệt về cú pháp rõ ràng, số chức năng khác biệt giữa phương pháp trait mặc định và hàm tham số mức mô-đun là gì? Một câu hỏi lớn mà tôi có là: liệu phương thức đặc điểm mặc định có định hình đơn thuần để sử dụng công văn tĩnh hay không, nếu nó là một đối tượng đặc điểm thì có phải là self không?

Sự khác biệt duy nhất tôi nhìn thấy ở đầu của tôi là impl đặc điểm có thể chọn ghi đè triển khai phương pháp mặc định, hy vọng/có thể cung cấp triển khai đáp ứng cùng một hợp đồng, trong khi tôi được bảo đảm rằng việc thực hiện mod::function luôn chạy cùng một mã chính xác bất kể điều gì (tốt hơn hay tệ hơn). Có gì khác? Câu trả lời có thay đổi nếu các loại liên quan hoặc đặc điểm mở rộng có liên quan không?

Trả lời

4

Bạn đã tự mình trả lời câu hỏi, xin chúc mừng!

Vì Rust chỉ có nguyên tắc quá tải/ghi đè thông qua các đặc điểm, sự khác biệt ngữ nghĩa cần thiết là một đặc điểm method có thể bị ghi đè và do đó được tùy chỉnh, trong khi chức năng miễn phí không thể.

Về mặt kỹ thuật, cả hai Trait::func(&self)mod::func<T: Trait>(&T) đều đơn điệu trong khi mod::func(&Trait) không phải là (và do đó sẽ phải chịu phí trên cao của cuộc gọi ảo).

Ngoài ra, có một chi tiết nhẹ bộ nhớ cho Trait::func(&self): một mục nhập khác trong bảng ảo. Nó có lẽ không đáng kể.

Tốt, lựa chọn thường là cuộc gọi phán đoán. Cho dù bạn mở cửa để tùy biến hay không là sự lựa chọn của bạn.

Các vấn đề liên quan