2014-06-21 5 views
5

मैं एक आदिम प्रकार u8 के लिए (serialize से, मेरे द्वारा परिभाषित नहीं) एक विशेषता ToHex के एक कार्यान्वयन प्रदान करना चाहते हैं:एक कार्यान्वयन प्रदान जब दोनों विशेषता और प्रकार यह टोकरा में नहीं हैं

impl ToHex for u8 { 
    fn to_hex(&self) -> String { 
     self.to_str_radix(16) 
    } 
} 

समस्या मैं इस संकलक त्रुटि मिलती है:

error: cannot provide an extension implementation where both trait and type are not defined in this crate 

मैं यह त्रुटि और उसके तर्क के कारण को समझते हैं, इस वजह से दोनों विशेषता और आदिम प्रकार मेरी कोड के लिए बाहरी हैं। लेकिन मैं इस स्थिति को कैसे संभाल सकता हूं और के लिए ToHex कार्यान्वयन प्रदान कर सकता हूं? और अधिक आम तौर पर आप इस तरह के मुद्दे को कैसे संभालेंगे, ऐसा लगता है कि यह समस्या सामान्य होनी चाहिए और इस तरह के प्रकारों को विस्तारित करना आसान और आसान होना चाहिए?

उत्तर

10

आप एक newtype struct का उपयोग करना चाहिए यह करने के लिए:

pub struct U8(pub u8) 

impl ToHex for U8 { 
    fn to_hex(&self) -> String { 
     let U8(x) = *self; 
     x.to_str_radix(16) 
    } 
} 

इसका अर्थ यह है, तथापि, कि आप U8 में u8 लपेट चाहिए जहाँ आप इस रूपांतरण करने के लिए की जरूरत है:

let x: u8 = 127u8 

// println!("{}", x.to_hex()); // does not compile 
println!("{}", U8(x).to_hex()); 

यह प्रदर्शन के मामले में बिल्कुल मुफ्त है।

+0

यह एक अच्छा हैक जो आप प्रस्तावित करते हैं। लेकिन मेरे मामले में मुझे चिंता है कि मैं इस तरह के सभी आदिम प्रकारों को लपेटने के लिए थोड़ा बोझिल होगा। – user3762625

+3

@ user3762625, यह एक हैक नहीं है, वास्तव में यह एकमात्र संभव तरीका है। आप उन लक्षणों के गुणों को लागू नहीं कर सकते हैं जिनके पास आपके स्वामित्व वाले प्रकारों के स्वामित्व नहीं हैं, और कोई कामकाज नहीं है लेकिन नए प्रकार हैं। –

+0

@ user3762625: ठीक है, प्रस्तुत किए गए मामले में, 'u8' के लिए' to_hex' फ्री-फ़ंक्शन होना आसान होगा (जिसे आप परिभाषित कर सकते हैं); जब आपको 'u8' पास करने की आवश्यकता होती है तो आपको केवल वास्तव में लपेटने की आवश्यकता होती है जहां' ToHex' की अपेक्षा की जाती है। –

3

मुझे एहसास है कि यह लगभग एक वर्ष पुराना है, लेकिन जवाब कभी स्वीकार नहीं किया गया था और मुझे लगता है कि मुझे एक वैकल्पिक समाधान मिला है, मैंने सोचा कि यहां दस्तावेज़ के लिए अच्छा होगा।

आदेश बजाय ToHex, क्यों एक नई विशेषता नहीं बना विस्तार करने के लिए कोशिश कर के, लक्षण के माध्यम से u8 की कार्यक्षमता बढ़ाने के लिए?

trait MyToHex { 
    fn to_hex(&self) -> String; 
} 

impl MyToHex for u8 { 
    fn to_hex(&self) -> String { 
     format!("{:x}", *self) 
    } 
} 

तो

fn main() { 
    println!("{}", (16).to_hex()); 
} 

की तरह इस्तेमाल किया यह लाभ यह है कि आप एक नया और ज़रूरत से ज़्यादा डेटा प्रकार के साथ हर u8 चर रैप करने के लिए की जरूरत नहीं है नहीं है।

नुकसान है कि आप अभी भी एक बाहरी समारोह में एक u8 उपयोग नहीं कर सकते (यानी एसटीडी पुस्तकालय या आपके द्वारा पर कोई नियंत्रण नहीं) है कि ToHex विशेषता की आवश्यकता है (व्लादिमीर Matveev समाधान इस मामले में काम करता है), लेकिन ओपी से ऐसा लगता है कि आप जो करना चाहते हैं वह u8 केवल आपके कोड के अंदर है।

संबंधित मुद्दे

 संबंधित मुद्दे