2017-12-21 102 views
6

Tôi cố gắng để viết hai đặc điểm mà người ta đòi hỏi khác được triển khai và đã nhận lỗi này:Làm thế nào để yêu cầu một đặc tính trong một đặc điểm khác một cách chính xác?

error[E0277]: the trait bound `T: ValTrait` is not satisfied 
    --> src/main.rs:20:1 
    | 
20 |/fn get<T: ValRequireTrait + std::fmt::Debug>(_t: T) { 
21 | |  println!("{:?}", T::VAL); 
22 | | } 
    | |_^ the trait `ValTrait` is not implemented for `T` 
    | 
    = help: consider adding a `where T: ValTrait` bound 
    = note: required by `ValRequireTrait` 

The code:

trait ValTrait<T = Self> { 
    const VAL: T; 
} 

trait ValRequireTrait<T: ValTrait = Self> {} 

#[derive(Debug, Copy, Clone)] 
struct A { 
    field: u64, 
} 

impl ValTrait for A { 
    const VAL: A = A { 
     field: 0u64 
    }; 
} 
impl ValRequireTrait for A {} 


fn get<T: ValRequireTrait + std::fmt::Debug>(_t: T) { 
    println!("{:?}", T::VAL); 
} 

fn main() { 
    let a = A { field: 6u64 }; 
    get(a); 
} 

Làm thế nào để làm điều này một cách chính xác? Nếu tôi làm những gì trình biên dịch nói tôi sẽ không cần ValRequireTrait vì nó sẽ vô dụng. Tôi muốn ValRequireTrait là một dấu hiệu cho thấy cấu trúc thực hiện đủ các phương pháp như tôi cần.

Nói cách khác, tôi mong đợi một yêu cầu như vậy được bắc cầu nên khi trong get() chức năng tôi yêu cầu một đặc điểm (ValRequireTrait), những người khác (ValTrait) sẽ được yêu cầu tự động mà không cần bất kỳ đặc điểm kỹ thuật trong các mã như trình biên dịch muốn.

Trả lời

2

Có vẻ như bạn muốn ValTraitsupertrait của ValRequireTrait. Một giới thiệu tốt có thể được tìm thấy trong the Rust book (2nd edition):

Sometimes, we may want a trait to be able to rely on another trait also being implemented wherever our trait is implemented, so that our trait can use the other trait’s functionality. The required trait is a supertrait of the trait we’re implementing.

Nếu bạn thay đổi dòng này:

trait ValRequireTrait<T: ValTrait = Self> {} 

vào đó, nó biên dịch tốt:

trait ValRequireTrait<T: ValTrait = Self>: ValTrait<T> {} 
+0

Trông vô lý với tôi lặp lại một điều nhiều lần. Có lời giải thích nào về lý do tại sao nó được làm như vậy không? Ý tôi là, chúng tôi đã yêu cầu 'T' là' ValTrait', tại sao yêu cầu 'ValRequireTrait' là' ValTrait'? Tôi thấy một sự lặp lại ở đây. –

+0

Bạn đúng là thừa và trình biên dịch quản lý để suy ra các đặc điểm giới hạn. Bạn không cần phải xác định đặc điểm ràng buộc một cách rõ ràng. Điều này cũng hoạt động: 'đặc điểm ValRequireTrait : ValTrait {}'. Tôi không phải là chuyên gia về rỉ sét, tôi hiện đang học bản thân mình. Nói chung tôi thấy rằng [rfcs] (https://github.com/rust-lang/rfcs) chứa thông tin có giá trị về * tại sao * mọi thứ được thực hiện theo một cách cụ thể. Tôi đã không tìm thấy bất cứ điều gì có liên quan trên supertraits mặc dù. – StarSheriff

+3

@VictorPolevoy 'ValRequireTrait' gần như vô dụng vì nó được tham số hóa theo cách tương tự' ValTrait'. Tôi nghi ngờ bạn đang tìm kiếm "đặc điểm ValRequireTrait: Sized + ValTrait {}' (không có tham số trên 'ValRequireTrait'). [Ví dụ] (https://play.rust-lang.org/?gist=d1a5cbda10d5b63e6082b8caada49911&version=stable) – trentcl

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