2016-03-04 16 views
7

के रूप में मैं एक संबद्ध प्रकार Trait::Associated के साथ एक विशेषता Trait है का उपयोग कर के लिए बाध्य। मैं की आवश्यकता होती है कि यह, उसके संबंधित प्रकार के आधार पर अनुक्रमित करने योग्य हो जैसा कि यहाँ दिखाया द्वारा विशेषता के लिए बाध्य करने के लिए कोशिश कर रहा हूँ:विशेषता विशेषता के जुड़े प्रकार पैरामीटर

use std::ops::Index; 

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

हालांकि, संकलक शिकायत है कि जुड़े प्रकार अस्पष्ट है

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

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

मैं भी करने की कोशिश की Self::Associated के रूप में संबंधित प्रकार का जिक्र करते हुए, लेकिन समझ में आता है कि संकलक प्रकार और विशेषता के बीच चक्रीय संदर्भ के बारे में विरोध करता है।

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" } 
} 

दुर्भाग्य से वह भी विफल रहता है:

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

मैं यहाँ कुछ अनुचित करने का प्रयास कर रहा हूँ

अंत में, मैं भी Trait के लिए Index को लागू करने को स्पष्ट रूप से करने की कोशिश की? क्या जेनेरिक का उपयोग किए बिना कुछ हासिल करने का कोई तरीका है?

Playpen link

उत्तर

9

आप करीब है, बहुत करीब हैं।

जवाब सरल है: Trait बस, स्वीकार नही करता है कि इसकी परिभाषा Trait के लिए किसी भी संदर्भ वर्तमान प्रकार को संदर्भित करता है के बाद आप सभी अन्य प्रकार के भी Trait को लागू करने का संदर्भ ले सकता है।

यह निर्दिष्ट करने के लिए कि आप एक विशिष्ट प्रकार चाहते हैं, आपको संकेत पर ध्यान देना चाहिए: <Type as Trait>::Associated का उपयोग करें, जहां Type वर्तमान प्रकार है।

तो, जब Trait को परिभाषित करने, तुम कैसे ठोस प्रकार का उल्लेख करते है जिसके लिए यह instantiated किया जाएगा? आप Self का उपयोग करते हैं!

समाधान है, इस प्रकार, यह है:

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

धन्यवाद, कि पूरी तरह से काम किया! संयोग से, क्या मेरा तीसरा प्रयास करने का कोई तरीका है (वह जहां विशेषता परिभाषा और 'impl' ब्लॉक अलग हैं)? अगर मैं 'impl' लाइन में 'सेल्फ' का उपयोग करने का प्रयास करता हूं, तो rustc शिकायत करता है। – Jean

+1

@Jean: वाक्य रचना होगा 'impl सूचकांक < :: एसोसिएटेड> T' के लिए लेकिन वहाँ यहाँ एक जुटना मुद्दा है। आप अपने क्रेट के प्रकार के लिए किसी अन्य क्रेट से केवल 'विशेषता' को लागू नहीं कर सकते हैं (किसी दिए गए प्रकार के लिए दिए गए गुण के विवादित कार्यान्वयन प्रदान करने वाले कई लोगों से बचने के लिए)। यहां, 'टी' आपके क्रेट के प्रकारों को सीमित नहीं कर रहा है ... इसलिए इसे प्रतिबंधित किया गया है। –

1

मुझे लगता है कि निम्नलिखित, अर्थ विज्ञान आप चाहते हैं प्रदान करता है अपने दूसरे प्रयास के दृष्टिकोण।

pub trait Trait { 
    type Associated; 
} 

impl<T> Index<T> for Trait<Associated=T> { 
    type Output=str; 
    fn index(&self, associated: T) -> &'static str { "sup" } 
} 
संबंधित मुद्दे