argmax फ़ंक्शन को लागू करते समय मुझे कुछ समस्याएं आती हैं। यहाँ एक MVCE है (v1 खेल के मैदान का लिंक):

fn main() {
    let c = [4,5,6,1];
    let min = argmin(&c);
    println!("{}", min);
}

fn argmin(arr: &[i32]) -> usize {
        arr.iter()
            .enumerate()
            .min_by_key(|(_, v)| v)
            .map(|(idx, _)| idx)
            .unwrap()
}

जिसके परिणामस्वरूप कुछ आजीवन त्रुटियां होती हैं:

error: lifetime may not live long enough
  --> src/main.rs:10:50
   |
10 |             .min_by_key(|(_, v): &(usize, &i32)| v)
   |                                  -             - ^ returning this value requires that `'1` must outlive `'2`
   |                                  |             |
   |                                  |             return type of closure is &'2 &i32
   |                                  let's call the lifetime of this reference `'1`

error: aborting due to previous error

दिया गया। इस बात की कोई गारंटी नहीं है कि वेक्टर के न्यूनतम मान का संदर्भ (संदर्भ) वेक्टर से अधिक है जिससे यह आ रहा है। इसने मुझे निम्नलिखित अनुकूलन के लिए प्रेरित किया (v2 खेल के मैदान):

fn main() {
    let c = [4,5,6,1];
    let min = argmin(&c);
    println!("{}", min);
}

fn argmin<'a>(arr: &'a [i32]) -> usize {
        arr.iter()
            .enumerate()
            .min_by_key(|(_, v): &'a (usize, &i32)| v)
            .map(|(idx, _)| idx)
            .unwrap()
}

मैं अब सोचूंगा, कि रस्ट यह पता लगा सकता है कि c और इसके न्यूनतम दोनों का जीवनकाल argmin के हस्ताक्षर से जानकारी के साथ समान है। लेकिन मुझे जो मिलता है वह एक और कंपाइलर त्रुटि है:

error[E0308]: mismatched types
  --> src/main.rs:10:34
   |
10 |             .min_by_key(|(_, v): &'a (usize, &i32)| v)
   |                                  ^^^^^^^^^^^^^^^^^ lifetime mismatch
   |
   = note: expected reference `&(usize, &i32)`
              found reference `&'a (usize, &i32)`
note: the anonymous lifetime #1 defined on the body at 10:25...
  --> src/main.rs:10:25
   |
10 |             .min_by_key(|(_, v): &'a (usize, &i32)| v)
   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...does not necessarily outlive the lifetime `'a` as defined on the function body at 7:11
  --> src/main.rs:7:11
   |
7  | fn argmin<'a>(arr: &'a [i32]) -> usize {
   |           ^^

error[E0308]: mismatched types
  --> src/main.rs:10:34
   |
10 |             .min_by_key(|(_, v): &'a (usize, &i32)| v)
   |                                  ^^^^^^^^^^^^^^^^^ lifetime mismatch
   |
   = note: expected reference `&(usize, &i32)`
              found reference `&'a (usize, &i32)`
note: the lifetime `'a` as defined on the function body at 7:11...
  --> src/main.rs:7:11
   |
7  | fn argmin<'a>(arr: &'a [i32]) -> usize {
   |           ^^
note: ...does not necessarily outlive the anonymous lifetime #1 defined on the body at 10:25
  --> src/main.rs:10:25
   |
10 |             .min_by_key(|(_, v): &'a (usize, &i32)| v)
   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

यहाँ क्या हो रहा है? मेरे लिए ऐसा लगता है कि फ़ंक्शन हस्ताक्षर में जीवनकाल min_by_key में से एक से मेल नहीं खा सकता है। जीवन काल का उपयोग करके हम इसे उचित तरीके से कैसे ठीक कर सकते हैं? क्या हम कर भी सकते हैं?

पीएस .: मुझे पता है कि यह आसानी से केवल एक क्लोन (.min_by_key(|(_, v)| v.clone())) का उपयोग करके लाइन 10 में तय किया जा सकता है।

1
pythonic833 30 जिंदा 2021, 12:13
आप आसानी से जीवन काल को आसानी से हटा सकते हैं और इसे उन्हें संभालने दे सकते हैं।
 – 
Netwave
30 जिंदा 2021, 13:38
टिप्पणी के लिए धन्यवाद। मैंने पहली बार यही कोशिश की, दूसरे कोड ब्लॉक पर एक नज़र डालें।
 – 
pythonic833
30 जिंदा 2021, 13:40
2
दिलचस्प बात यह है कि और भी सरल fn argmin(arr: &[i32]) { let _min = arr.iter().min_by_key(|v| v).unwrap(); } भी निर्माण करने में विफल रहता है ( खेल का मैदान) पहले स्निपेट के समान आजीवन त्रुटि के साथ। मैं उस कोड के साथ वास्तविक समस्या के बारे में उत्सुक हूं - ऐसा नहीं है कि बंद करने से स्थानीय मूल्य का संदर्भ मिलता है, यह तर्क में प्राप्त संदर्भ देता है, और वह संदर्भ "जाहिर है" काफी लंबा रहता है। min_by_key(|v| v) को केवल min() कंपाइल से बदलना।
 – 
user4815162342
30 जिंदा 2021, 13:53

1 उत्तर

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

तो, यह थोड़ा मुश्किल है, लेकिन यह दोहरे संदर्भ के कारण है। अगर मैं सही हूँ। दोहरे संदर्भ &(usize, &i32) पर ध्यान दें। तो, वास्तव में आपको एक &usize और एक &&i32 मिल रहा है। इसे हल करने के लिए, क्लोजर में बाहरी संदर्भ का केवल मिलान करें:

fn argmin(arr: &[i32]) -> usize {
        arr.iter()
            .enumerate()
            .min_by_key(|&(_, v): &(usize, &i32)| v)
            .map(|(idx, _)| idx)
            .unwrap()
}

खेल का मैदान

1
Netwave 30 जिंदा 2021, 13:59
उत्तर के लिए बहुत बहुत धन्यवाद, जो समाधान को स्पष्ट करता है। तो वास्तविक समस्या यह थी कि दोहरे संदर्भ &&i32 में डिफ़ॉल्ट रूप से वेक्टर की तुलना में एक और जीवनकाल होता है?
 – 
pythonic833
30 जिंदा 2021, 14:08
@pythonic833, बिल्कुल
 – 
Netwave
30 जिंदा 2021, 14:49