क्या मानचित्र मूल्य द्वारा या गो में संदर्भ द्वारा पारित किए जाते हैं?


94

क्या मूल्य में नक्शे को गो या संदर्भ द्वारा पारित किया जाता है?

निम्नलिखित के रूप में किसी फ़ंक्शन को परिभाषित करना हमेशा संभव होता है, लेकिन क्या यह एक ओवरकिल है?

func foo(dat *map[string]interface{}) {...}

वापसी मूल्य के लिए एक ही सवाल। क्या मुझे नक्शे के लिए एक सूचक वापस करना चाहिए, या मान के रूप में नक्शा वापस करना चाहिए?

अनावश्यक डेटा कॉपी से बचने के लिए इरादा निश्चित रूप से है।


4
blog.golang.org/go-maps-in-action : मानचित्र प्रकार संदर्भ प्रकार हैं, जैसे संकेत या स्लाइस, और इसलिए ऊपर m का मान शून्य है; यह एक प्रारंभिक नक्शे की ओर इशारा नहीं करता है। पढ़ते समय एक शून्य मानचित्र एक खाली मानचित्र की तरह व्यवहार करता है, लेकिन एक शून्य मानचित्र पर लिखने का प्रयास एक रनटाइम आतंक का कारण होगा; ऐसा मत करो। एक मानचित्र आरंभ करने के लिए, मेकअप समारोह में बनाया का उपयोग करें
MH-cbon

2
गो में सब कुछ मूल्य से पारित है। कुछ मान बिंदु या संरचनाएँ होते हैं जिनमें संकेत होते हैं। (आप *mapकुछ मामलों में एक चाहते हो सकते हैं , अगर आपको एक पते पर मानचित्र मान को फिर से असाइन करने की आवश्यकता है)
जिमबॉव

mh-cbon, Go में कोई संदर्भ प्रकार नहीं हैं।
इनक गमूस

@ mh-cbon मैं एक संदर्भ प्रकार के बारे में बात नहीं कर रहा था। मैं पूछ रहा था कि क्या एक नक्शा संदर्भ द्वारा पारित किया गया है, जो यह पूछने के बराबर है कि क्या मानचित्र का पता तर्क के रूप में पारित किया गया है या नक्शे की "प्रतिलिपि" (मूल्य से पारित)।
चमीक

1
@ mh-cbon बिल्कुल, नक्शे हाम के संकेत हैं।
इनक गमुस

जवाबों:


83

इस सूत्र में आपको अपना उत्तर मिलेगा:

गोलंग: इसके संदर्भ का उपयोग करते हुए एक मानचित्र तक पहुँचना

आपको मैप के साथ पॉइंटर का उपयोग करने की आवश्यकता नहीं है।

मानचित्र प्रकार संदर्भ प्रकार हैं, जैसे संकेत या स्लाइस [1]

यदि आपको सत्र बदलने की आवश्यकता है तो आप एक पॉइंटर का उपयोग कर सकते हैं:

map[string]*Session

https://blog.golang.org/go-maps-in-action


16
किसी भी गड्ढे से बचने के लिए, इस बात से अवगत रहें कि मानचित्र केवल संदर्भ द्वारा एक बार आरंभिक रूप से पारित हो जाते हैं , और जब किसी फ़ंक्शन के अंदर पुन: आरंभ किया जाता है, तो मूल संदर्भ अपडेट नहीं किया जाएगा। यहाँ एक उदाहरणीय खेल का मैदान उदाहरण है: play.golang.org/p/Q6vrAmmJWR6 या डेव चेनी द्वारा एक पूर्ण लेख dave.cheney.net/2017/04/29/there-is-no-pass-by-reference-in-go
सिंद्रे मायरेन

19

यहाँ से कुछ भाग हैं यदि कोई नक्शा संदर्भ चर नहीं है, तो वह क्या है? डेव चेनी द्वारा:

एक मानचित्र मान एक runtime.hmapसंरचना के लिए एक संकेतक है ।

और निष्कर्ष:

निष्कर्ष

मैप्स, जैसे चैनल, लेकिन स्लाइस के विपरीत, रनटाइम प्रकार के लिए केवल संकेत हैं। जैसा कि आपने ऊपर देखा, एक नक्शा एक runtime.hmap संरचना के लिए एक संकेतक है ।

मैप्स में एक ही प्रोग्राम में किसी अन्य पॉइंटर मान के समान पॉइंटर शब्दार्थ होते हैं। कोई जादू नहीं है जो संकलक द्वारा कार्यों में कॉल द्वारा मानचित्र सिंटैक्स के पुनर्लेखन को सहेजता है runtime/hmap.go

और mapवाक्य रचना के इतिहास / स्पष्टीकरण के बारे में एक दिलचस्प सा :

यदि नक्शे पॉइंटर्स हैं, तो क्या वे नहीं होने चाहिए *map[key]value?

यह एक अच्छा सवाल है कि अगर नक्शे सूचक मान हैं, तो अभिव्यक्ति make(map[int]int)प्रकार के साथ एक मान क्यों लौटाती है map[int]int। क्या यह वापस नहीं आना चाहिए *map[int]int? इयान टेलर ने इसका जवाब हाल ही में एक गोलंग-नट के धागे 1 में दिया

बहुत शुरुआती दिनों में जिसे हम मानचित्र कहते हैं, उसे पॉइंटर्स के रूप में लिखा गया था, इसलिए आपने लिखा था *map[int]int। हम इससे दूर चले गए, जब हमें महसूस हुआ कि कोई भी mapबिना लिखे नहीं रहता है *map

यकीनन से प्रकार का नाम बदलने *map[int]intके लिए map[int]intहै, जबकि भ्रमित प्रकार एक सूचक की तरह नहीं दिखता है क्योंकि, एक सूचक आकार का मूल्य जो dereferenced नहीं किया जा सकता से भ्रमित भी कम था।


3

सं। नक्शे डिफ़ॉल्ट रूप से संदर्भ हैं।

    package main

    import "fmt"

    func mapToAnotherFunction(m map[string]int) {
        m["hello"] = 3
        m["world"] = 4
        m["new_word"] = 5
    }

    // func mapToAnotherFunctionAsRef(m *map[string]int) {
    // m["hello"] = 30
    // m["world"] = 40
    // m["2ndFunction"] = 5
    // }

    func main() {
        m := make(map[string]int)
        m["hello"] = 1
        m["world"] = 2

        // Initial State
        for key, val := range m {
            fmt.Println(key, "=>", val)
        }

        fmt.Println("-----------------------")

        mapToAnotherFunction(m)
        // After Passing to the function as a pointer
        for key, val := range m {
            fmt.Println(key, "=>", val)
        }

        // Try Un Commenting This Line
        fmt.Println("-----------------------")

        // mapToAnotherFunctionAsRef(&m)
        // // After Passing to the function as a pointer
        // for key, val := range m {
        //  fmt.Println(key, "=>", val)
        // }

        // Outputs
        // hello => 1
        // world => 2
        // -----------------------
        // hello => 3
        // world => 4
        // new_word => 5
        // -----------------------

    }

गोलंग ब्लॉग से-

मानचित्र प्रकार संदर्भ प्रकार हैं, जैसे संकेत या स्लाइस, और इसलिए ऊपर m का मान शून्य है; यह एक प्रारंभिक नक्शे की ओर इशारा नहीं करता है। पढ़ते समय एक शून्य मानचित्र एक खाली मानचित्र की तरह व्यवहार करता है, लेकिन एक शून्य मानचित्र पर लिखने का प्रयास एक रनटाइम आतंक का कारण होगा; ऐसा मत करो। एक नक्शे को इनिशियलाइज़ करने के लिए, बिल्ट इन मेक फंक्शन का उपयोग करें:

// Ex of make function
m = make(map[string]int)

इसके साथ कोड स्निपेट लिंक प्ले।

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