मेरे पास जंग में नेस्टेड कोड की यह राक्षसी है, जो ठीक काम करती है।

यदि संभव हो तो एक गिट रेपो की स्थानीय कॉन्फ़िगरेशन डेटा-संरचना खोलने का विचार है, अन्यथा बस एक खाली GitConfig लौटाएं। कॉल की एक श्रृंखला है जो वर्तमान निर्देशिका को खोजने के लिए आवश्यक है, इसमें से एक गिट रेपो के लिए खोजें, रेपो खोलें, और फिर इसके भीतर कॉन्फ़िगरेशन खोलें, जिनमें से सभी या तो एक त्रुटि फेंक सकते हैं, या वापस आ सकते हैं None. मुझे परवाह नहीं है कि कौन सी त्रुटि फेंकी गई है, (या जब None लौटाया जाता है) सिवाय इसके कि जब कोई त्रुटि फेंकी जाती है (या None है लौटा दी जाती है), एक खाली GitConfig है पूरी चेन से लौटा।

       let local = match env::current_dir() {
            Err(_) => GitConfig::new().unwrap(),
            Ok(cwd) => {
                match find_git_root(&cwd) {
                    None => GitConfig::new().unwrap(),
                    Some(git_path) => {
                        match Repository::open(&git_path) {
                            Err(_) => GitConfig::new().unwrap(),
                            Ok(repo) => {
                                match repo.config() {
                                    Err(_) => GitConfig::new().unwrap(),
                                    Ok(config) => {
                                        config.open_level(Local).unwrap()
                                    }
                                }
                            }
                        }
                    }
                }
            }
        };

मैं map() and_then() और अन्य जैसे संयोजकों के उपयोग के साथ इसे और अधिक कार्यात्मक शैली में दोबारा करने की कोशिश कर रहा हूं लेकिन मेरे सिर में एक स्टैक ओवरफ़्लो है जो इसे समझने की कोशिश कर रहा है। मुझे यकीन है कि ऐसा करने का एक तरीका है, श्रृंखला में Result और Options दोनों के रिटर्न प्रकारों को ध्यान में रखते हुए, और यह भी तथ्य कि कंक्रीट Error प्रकार के भीतर है Results कॉल दर कॉल भिन्न होते हैं।

क्या इसे कार्यात्मक रूप से लिखने का एक अच्छा, मुहावरेदार तरीका है, श्रृंखला के नीचे किसी भी त्रुटि को पारित करते हुए ताकि इसे बहुत अंत में ok_or_else() या map_or_else() या इसी तरह से संभाला जा सके? और कोड को साफ-सुथरा बनाने और पढ़ने में अधिक आसान बनाने के लिए मैं नेस्टिंग को कैसे समतल कर सकता हूं?

-1
Brad 9 अप्रैल 2020, 13:46

1 उत्तर

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

mdo या map_for जो आपको इस कोड को कुछ इस तरह सरल बनाने की अनुमति देता है:

map_for!{
    cwd <- env::current_dir().ok();
    git_path <- find_git_root (&cwd);
    repo <- Repository::open (&git_path).ok();
    config <- repo.config().ok();
    => config.open_level(Local).unwrap()
}.unwrap_or_else (|| GitConfig::new().unwrap());

या आप इसे ? ऑपरेटर और एक फ़ंक्शन (या बंद) के साथ कर सकते हैं:

(|| {
    let cwd = env::current_dir().ok()?;
    let git_path = find_git_root (&cwd)?;
    let repo = Repository::open (&git_path).ok()?;
    let config = repo.config().ok()?;
    config.open_level(Local).ok()
})().unwrap_or_else (|| GitConfig::new().unwrap());

आखिरकार, आप इसे try ब्लॉक करें, लेकिन वे फिलहाल अस्थिर हैं।

पूर्ण प्रकटीकरण: मैं map_for क्रेट का लेखक हूं।

4
Jmb 10 अप्रैल 2020, 06:50