जंग में एक "मौलिक प्रकार" क्या है?


37

कहीं मैंने "मौलिक प्रकार" (और इसकी विशेषता #[fundamental]) शब्द को उठाया है और अभी मैं इसके बारे में अधिक जानना चाहता हूं। मैं अस्पष्ट रूप से इसे कुछ स्थितियों में सुसंगत नियमों को शिथिल करने के बारे में याद करता हूं। और मुझे लगता है कि संदर्भ प्रकार ऐसे मौलिक प्रकार हैं।

दुर्भाग्य से, वेब पर खोज करने से मुझे बहुत दूर नहीं जाना पड़ा। रस्ट संदर्भ में इसका उल्लेख नहीं है (जहां तक ​​मैं देख सकता हूं)। मुझे सिर्फ ट्यूपल्स को मौलिक बनाने और विशेषता को प्रस्तुत करने वाले RFC के बारे में एक समस्या मिली । हालाँकि, RFC में मूलभूत प्रकारों के बारे में एक ही पैराग्राफ है:

  • एक #[fundamental]प्रकार Fooवह है जहां एक कंबल को लागू करने से अधिक Fooएक ब्रेकिंग परिवर्तन होता है। जैसा कि वर्णित है, &और &mutमौलिक हैं। इस विशेषता को लागू किया जाएगा Box, जिससे Box व्यवहार के साथ &और समान व्यवहार हो &mut

मुझे समझने में शब्दांकन काफी कठिन लगता है और मुझे ऐसा लगता है कि मुझे मूलभूत प्रकारों के बारे में इस बिट को समझने के लिए पूर्ण RFC के गहन ज्ञान की आवश्यकता है। मैं उम्मीद कर रहा था कि कोई व्यक्ति कुछ सरल शब्दों में मौलिक प्रकारों की व्याख्या कर सकता है (बिना बहुत सरल किए, निश्चित रूप से)। यह प्रश्न ज्ञान के आसान-से-आसान टुकड़े के रूप में भी काम करेगा।

मूलभूत प्रकारों को समझने के लिए, मैं इन सवालों के जवाब देना चाहूंगा (मुख्य के अलावा "वे भी क्या हैं?" प्रश्न, निश्चित रूप से)

  • क्या मौलिक प्रकार गैर-मौलिक से अधिक कर सकते हैं?
  • क्या मैं एक पुस्तकालय लेखक के रूप में, अपने कुछ प्रकारों को चिह्नित करने से किसी तरह से लाभान्वित हो सकता हूं #[fundamental]?
  • मूल भाषा या मानक पुस्तकालय से कौन से प्रकार मौलिक हैं?

जवाबों:


34

आम तौर पर, यदि किसी लाइब्रेरी में जेनेरिक प्रकार होता है 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 जारी है ।


1
बहुत बढ़िया जवाब! आदिम प्रकार के बारे में: वहाँ केवल एक मुट्ठी सामान्य आदिम प्रकार हैं: &T, &mut T, *const T, *mut T, [T; N], [T], fnसूचक और tuples। और उन सभी का परीक्षण करना (कृपया मुझे बताएं कि क्या यह कोड समझ में नहीं आता है) ऐसा लगता है कि संदर्भ केवल मौलिक आदिम प्रकार हैं । दिलचस्प। मुझे इस तर्क को जानने में दिलचस्पी होगी कि दूसरे क्यों नहीं हैं, खासकर कच्चे संकेत। लेकिन यह इस सवाल का दायरा नहीं है, मुझे लगता है।
लुकास कालबर्टोड

1
@LukasKalbertodt आदिम प्रकार की जानकारी के लिए धन्यवाद। मैंने आपके परीक्षणों में जोड़ा है। संदर्भ बनाम संकेत के बारे में तर्क के लिए, RFC पुल अनुरोध में इस टिप्पणी की जाँच करें।
SCappella

संदर्भ अस्थिर विशेषताओं का दस्तावेज़ नहीं करता है, इसलिए आपको यह वहां नहीं मिला।
हवीवी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.