2016-03-04 19 views
7

Tôi có một đặc điểm Trait với loại được liên kết Trait::Associated. Tôi cố gắng để ràng buộc các đặc điểm bằng cách yêu cầu mà nó được lập chỉ mục theo loại liên quan của nó, như ở đây:Trait bị ràng buộc sử dụng loại được liên kết của đặc điểm làm thông số

use std::ops::Index; 

pub trait Trait: Index<Trait::Associated> { 
    type Associated; 
} 

Tuy nhiên, trình biên dịch phàn nàn rằng các loại liên quan đến rất mơ hồ

error: ambiguous associated type; specify the type using the syntax <Type as Trait>::Associated [E0223]

pub trait Trait: Index<Trait::Associated> 
         ^~~~~~~~~~~~~~~~~ 

Tôi cũng đã cố gắng đề cập đến loại liên quan là Self::Associated, nhưng dễ hiểu thì trình biên dịch phản đối về tham chiếu tuần hoàn giữa loại và đặc điểm.

Cuối cùng, tôi cũng đã cố gắng một cách rõ ràng thực hiện Index cho Trait:

pub trait Trait { 
    type Associated; 
} 

impl<T: Trait> Index<T::Associated> for T { 
    type Output = str; 
    fn index(&self, associated: T::Associated) -> &'static str { "sup" } 
} 

Thật không may thất bại quá:

error: type parameter T must be used as the type parameter for some local type (e.g. MyStruct<T>); only traits defined in the current crate can be implemented for a type parameter

Tôi đang cố gắng làm điều gì đó không hợp lý ở đây? Có cách nào để đạt được một cái gì đó tương tự, mà không cần phải sử dụng Generics?

Playpen link.

Trả lời

9

Bạn đang ở rất gần.

Câu trả lời rất đơn giản: các Trait đơn giản là không giả định rằng bất kỳ tài liệu tham khảo để Trait trong định nghĩa của nó đề cập đến loại hiện nay, sau khi tất cả các bạn có thể muốn tham khảo các loại khác cũng thực hiện Trait.

Để xác định rằng bạn muốn có một loại cụ thể, bạn nên lưu ý gợi ý: sử dụng <Type as Trait>::Associated, trong đó Type là loại hiện tại.

Vì vậy, khi xác định Trait, làm thế nào để bạn tham chiếu đến loại bê tông mà nó sẽ được khởi tạo? Bạn sử dụng Self!

Các giải pháp, do đó, là:

pub trait Trait: Index<<Self as Trait>::Associated> { 
    type Associated; 
} 
+0

Cảm ơn, điều đó đã hoạt động hoàn hảo! Ngẫu nhiên, có cách nào để thực hiện công việc cố gắng thứ ba của tôi không (cách xác định đặc điểm và khối 'impl' tách biệt)? Nếu tôi cố gắng sử dụng 'Self' trong dòng' impl', rustc than phiền. – Jean

+1

@Jean: cú pháp sẽ là 'impl Chỉ mục < :: Liên kết> cho T' nhưng có sự cố kết hợp ở đây. Bạn không thể chỉ thực hiện một 'trait' từ một thùng khác cho một loại thùng của riêng bạn (để tránh nhiều người cung cấp việc triển khai mâu thuẫn của một đặc điểm đã cho cho một kiểu nhất định). Ở đây, 'T' không hạn chế các loại thùng của bạn ... nên nó bị cấm. –

1

Tôi nghĩ rằng những điều sau đây cung cấp ngữ nghĩa mà bạn muốn, dùng phương pháp của nỗ lực thứ hai của bạn.

pub trait Trait { 
    type Associated; 
} 

impl<T> Index<T> for Trait<Associated=T> { 
    type Output=str; 
    fn index(&self, associated: T) -> &'static str { "sup" } 
} 
Các vấn đề liên quan