मैं वर्तमान में रस्ट पुस्तक पढ़ रहा हूँ, और मैं अभी इस विषय पर पहुँचा हूँ closures. एक विवरण जिसने मुझे चौंका दिया है, वह यह है कि रस्ट पुस्तक कहती है कि

क्लोजर के लिए आपको पैरामीटर के प्रकार को एनोटेट करने की आवश्यकता नहीं है

मैंने तुरंत इसका परीक्षण किया, क्योंकि यह वास्तव में काउंटर-सहज ज्ञान युक्त दिखाई देता है कि रस्ट आमतौर पर कैसे काम करता है। इस प्रकार, मैंने कॉपी किया है ठीक उसी तरह जैसे उन्होंने इस्तेमाल किया, इसे मेरे कोड में चिपकाया, और... एक त्रुटि मिली:

fn some_closure() {
    let expensive_closure = |num| {
        println!("calculating slowly...");
        thread::sleep(Duration::from_secs(2));
        num
    };
}
error[E0282]: type annotations needed
  --> src/main.rs:14:30
   |
14 |     let expensive_closure = |num| {
   |                              ^^^ consider giving this closure parameter a type

error: aborting due to previous error

मुझे यकीन है कि उस त्रुटि का अर्थ पता है, फिर भी मैं इससे भ्रमित हूं, क्योंकि न केवल पुस्तक, बल्कि reference निर्दिष्ट करें कि किसी एनोटेशन की आवश्यकता नहीं है, फिर भी मुझे यह त्रुटि मिल रही है।

क्या यह अभी हाल ही में हुआ एक बदलाव है जिसे अभी तक प्रलेखित नहीं किया गया है, या कुछ ऐसा है जिसे मैं गलत समझ रहा हूँ?

1
Thörni 7 जून 2021, 12:52

2 जवाब

सबसे बढ़िया उत्तर

कंपाइलर को तर्क के प्रकार को किसी तरह से निकालने में सक्षम होना चाहिए, यह स्पष्ट प्रकार के एनोटेशन के माध्यम से हो सकता है जैसे कि num: i32 या प्रासंगिक जानकारी जैसे कि

fn use_some_closure() {
    let expensive_closure = |num| {
        println!("calculating slowly...");
        thread::sleep(Duration::from_secs(2));
        num
    };
    expensive_closure(42);
}

एनोटेशन या उपयोग के बिना यह पता लगाने का कोई तरीका नहीं है कि num क्या है।

खेल का मैदान

4
sebpuetz 7 जून 2021, 12:57

पुस्तक, लेकिन संदर्भ यह भी निर्दिष्ट करता है कि कोई एनोटेशन की आवश्यकता नहीं है, फिर भी मुझे यह त्रुटि मिल रही है।

नहीं, पुस्तक का मुख्य शब्द और संदर्भ आवश्यक है, जो आवश्यक से भिन्न है। किसी चीज़ की प्रासंगिक रूप से आवश्यकता तब भी हो सकती है, जब उसकी आम तौर पर आवश्यकता न हो।

बंद करने के लिए भेद "स्थैतिक कार्यों" (fn) के विरोध में है, जिसके लिए एनोटेशन एक वाक्यविन्यास आवश्यकता है: आप टाइप एनोटेशन प्रदान किए बिना वैध स्थिर कार्य नहीं लिख सकते हैं, जबकि आम तौर पर आप बोलते हैं टाइप एनोटेशन के बिना क्लोजर लिख सकते हैं।

हालांकि संकलक को अभी भी बंद होने के ठोस प्रकार को जानने की जरूरत है, जिसके लिए पैरामीटर और रिटर्न प्रकारों का अनुमान लगाने में सक्षम होना आवश्यक है। यदि ऐसा नहीं हो सकता है क्योंकि पर्याप्त बाधाएं नहीं हैं, तो यह शिकायत करेगा और स्पष्ट रूप से निर्दिष्ट प्रकारों की आवश्यकता होगी।

आपके उदाहरण में, num के प्रकार में कोई बाधा नहीं है, इसलिए rustc के पास यह जानने का कोई तरीका नहीं है कि num का कंक्रीट प्रकार क्या है, और इसलिए यह अनुमान लगाने में सक्षम नहीं है बंद करने का ठोस प्रकार क्या होना चाहिए।

लेकिन ज्यादातर मामलों में उदा।

let it = repeat(5).map(|x| x+1);

संकलक इससे खुश है, क्योंकि बंद करने के इनपुट और आउटपुट प्रकार आवश्यक रूप से map प्रदान करते हैं, जो कि Repeat::Item है, जो इस मामले में i32 है (क्योंकि यही पूर्णांक शाब्दिक है अन्य बाधाओं को छोड़कर डिफ़ॉल्ट)।

4
Masklinn 7 जून 2021, 14:31