आम तौर पर, यदि किसी लाइब्रेरी में जेनेरिक प्रकार होता है Foo<T>
, तो डाउनस्ट्रीम क्रेट उस पर लक्षण लागू नहीं कर सकता है, भले ही T
वह कुछ स्थानीय प्रकार का हो। उदाहरण के लिए,
( crate_a
)
struct Foo<T>(pub t: T)
( crate_b
)
use crate_a::Foo;
struct Bar;
// This causes an error
impl Clone for Foo<Bar> {
fn clone(&self) -> Self {
Foo(Bar)
}
}
एक ठोस उदाहरण के लिए जो खेल के मैदान पर काम करता है (जो एक त्रुटि देता है),
use std::rc::Rc;
struct Bar;
// This causes an error
// error[E0117]: only traits defined in the current crate
// can be implemented for arbitrary types
impl Default for Rc<Bar> {
fn default() -> Self {
Rc::new(Bar)
}
}
(खेल का मैदान)
यह आम तौर पर टोकरा लेखक को डाउनस्ट्रीम क्रेट्स को तोड़ने के बिना लक्षणों के कार्यान्वयन (कंबल) को जोड़ने में सक्षम बनाता है। यह उन मामलों में बहुत अच्छा है, जहां यह शुरू में निश्चित नहीं है कि किसी प्रकार को किसी विशेष गुण को लागू करना चाहिए, लेकिन बाद में यह स्पष्ट हो जाता है कि यह होना चाहिए। उदाहरण के लिए, हमारे पास कुछ प्रकार के संख्यात्मक प्रकार हो सकते हैं जो शुरू में लक्षणों को लागू नहीं करते हैं num-traits
। उन लक्षणों को बाद में एक ब्रेकिंग परिवर्तन की आवश्यकता के बिना जोड़ा जा सकता है।
हालाँकि, कुछ मामलों में, लाइब्रेरी लेखक चाहते हैं कि डाउनस्ट्रीम क्रेट्स स्वयं को लागू करने में सक्षम हों। यह वह #[fundamental]
विशेषता है जहां विशेषता आती है। जब किसी प्रकार पर रखा जाता है, तो उस प्रकार के लिए वर्तमान में लागू नहीं किया गया कोई भी गुण लागू नहीं किया जाएगा (ब्रेकिंग परिवर्तन को छोड़कर)। नतीजतन, डाउनस्ट्रीम क्रेट्स उस प्रकार के लिए लक्षण लागू कर सकते हैं जब तक कि एक प्रकार का पैरामीटर स्थानीय है (यह तय करने के लिए कुछ जटिल नियम हैं कि किस प्रकार के पैरामीटर इसके लिए गणना करते हैं)। चूँकि मौलिक प्रकार किसी दिए गए विशेषता को लागू नहीं करेगा, इसलिए यह समस्या बिना किसी सहारे के मुद्दों के कारण स्वतंत्र रूप से लागू की जा सकती है।
उदाहरण के लिए, Box<T>
चिह्नित किया गया है #[fundamental]
, इसलिए निम्न कोड ( Rc<T>
उपरोक्त संस्करण के समान ) काम करता है। Box<T>
लागू नहीं करता है Default
(जब तक कि T
लागू न हो Default
) इसलिए हम यह मान सकते हैं कि यह भविष्य में नहीं होगा क्योंकि Box<T>
यह मौलिक है। ध्यान दें कि लागू करने Default
के लिए Bar
समस्या का कारण बन, तब से Box<Bar>
पहले से ही लागू करता Default
।
struct Bar;
impl Default for Box<Bar> {
fn default() -> Self {
Box::new(Bar)
}
}
(खेल का मैदान)
दूसरी ओर, लक्षण भी चिह्नित किए जा सकते हैं #[fundamental]
। यह मौलिक प्रकारों का दोहरा अर्थ है। यदि कोई भी प्रकार वर्तमान में एक मौलिक विशेषता को लागू नहीं करता है, तो यह माना जा सकता है कि यह प्रकार भविष्य में इसे लागू नहीं करेगा (फिर, एक ब्रेकिंग परिवर्तन को रोकते हुए)। मुझे यकीन नहीं है कि यह कैसे व्यवहार में उपयोग किया जाता है। कोड में (नीचे लिंक किया गया है), FnMut
उस नोट के साथ मौलिक रूप से चिह्नित किया जाता है जिसकी उसे regex (कुछ के बारे में &str: !FnMut
) की आवश्यकता होती है । मुझे नहीं पता कि यह regex
टोकरा में कहाँ उपयोग किया जाता है या अगर यह कहीं और उपयोग किया जाता है।
सिद्धांत रूप में, यदि Add
विशेषता को मौलिक रूप से चिह्नित किया गया था (जिस पर चर्चा की गई है) इसका उपयोग उन चीजों के बीच जोड़ को लागू करने के लिए किया जा सकता है जो पहले से ही नहीं हैं। उदाहरण के लिए, जोड़ना [MyNumericType; 3]
(बिंदुवार), जो कुछ स्थितियों में उपयोगी हो सकता है (बेशक, [T; N]
मौलिक बनाने से यह भी अनुमति होगी)।
आदिम मौलिक प्रकार हैं &T
, &mut T
( सभी सामान्य आदिम प्रकारों के प्रदर्शन के लिए यहां देखें )। मानक पुस्तकालय में, Box<T>
और Pin<T>
इसे मौलिक के रूप में भी चिह्नित किया जाता है।
मानक पुस्तकालय में मौलिक लक्षण हैं Sized
, Fn<T>
, FnMut<T>
, FnOnce<T>
और Generator
।
ध्यान दें कि #[fundamental]
वर्तमान में विशेषता अस्थिर है। ट्रैकिंग समस्या # 29635 जारी है ।
&T
,&mut T
,*const T
,*mut T
,[T; N]
,[T]
,fn
सूचक और tuples। और उन सभी का परीक्षण करना (कृपया मुझे बताएं कि क्या यह कोड समझ में नहीं आता है) ऐसा लगता है कि संदर्भ केवल मौलिक आदिम प्रकार हैं । दिलचस्प। मुझे इस तर्क को जानने में दिलचस्पी होगी कि दूसरे क्यों नहीं हैं, खासकर कच्चे संकेत। लेकिन यह इस सवाल का दायरा नहीं है, मुझे लगता है।