जंग में, निम्नलिखित कार्य कानूनी है:

fn unwrap<T>(s:Option<T>) -> T {
    s.unwrap()
}

यह s का स्वामित्व लेता है, अगर यह एक None है, और s की सामग्री का स्वामित्व लौटाता है (जो कानूनी है क्योंकि Option इसकी सामग्री का मालिक है)।

मैं हस्ताक्षर के साथ एक समान कार्य लिखने की कोशिश कर रहा था

fn unwrap_set<T>(s: BTreeSet<T>) -> T { 
  ...
}

विचार यह है कि यह तब तक घबराता है जब तक s का आकार 1 न हो, जिस स्थिति में यह एकल तत्व लौटाता है। ऐसा लगता है कि यह उसी कारण से संभव होना चाहिए unwrap संभव है, हालांकि BTreeSet पर किसी भी तरीके का सही हस्ताक्षर नहीं था (उन्हें वापसी प्रकार T की आवश्यकता होगी)। निकटतम take था, और मैंने करने की कोशिश की

    let mut s2 = s;
    let v: &T = s2.iter().next().unwrap();
    s2.take(v).unwrap()

लेकिन यह विफल रहा।

क्या unwrap_set जैसा फंक्शन लिखना संभव है?

0
xuanji 22 जिंदा 2020, 06:22

1 उत्तर

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

ऐसा करने का सबसे आसान तरीका होगा BTreeSet<T>< का इस्तेमाल करना /a> IntoIterator का क्रियान्वयन , जो आपको स्वामित्व वाले मूल्यों को एक बार में एक सेट से आसानी से निकालने की अनुमति देगा:

fn unwrap_set<T>(s: BTreeSet<T>) -> T {
    let mut it = s.into_iter();
    if let Some(first) = it.next() {
        if let None = it.next() {
            return first;
        }
    }
    panic!("set must have a single value");
}

यदि आप परोक्ष रूप से IntoIterator पर भरोसा करना चाहते हैं तो आप एक सामान्य लूप का भी उपयोग कर सकते हैं, लेकिन मुझे नहीं लगता कि यह इस तरह से पढ़ने योग्य है इसलिए मैं शायद ऐसा नहीं करूंगा:

fn unwrap_set<T>(s: BTreeSet<T>) -> T {
    let mut result = None;
    for item in s {
        // If there is a second value, bail out
        if let Some(_) = result {
            result = None;
            break;
        }
        result = Some(item);
    }
    return result.expect("set must have a single value");
}
1
Ömer Erden 22 जिंदा 2020, 05:02