मैं इस सरल गोलंग कोड में भाग गया और यहां गो के व्यवहार से हैरान था। क्या कोई समझा सकता है कि यहां क्या हो रहा है, और नीचे दिए गए कोड को सही तरीके से कैसे लिखना है?

जैसा कि आप देख सकते हैं, मेरे पास एक map है, जहां कुंजी int का array है। मैं कुछ मान जोड़ता हूं और फिर मैं map के माध्यम से लूप करता हूं, प्रत्येक कुंजी को slice में परिवर्तित करता हूं और प्रत्येक कुंजी को [][]int प्रकार के ऑब्जेक्ट में जोड़ता हूं।

func test() {
    myMap := make(map[[3]int]bool)
    myMap[[3]int{1, 2, 3}] = true
    myMap[[3]int{0, 5, 4}] = true
    myMap[[3]int{9, 7, 1}] = true
    myMap[[3]int{0, 2, 8}] = true
    array := [][]int{}

    for val := range myMap {
        array = append(array, val[:])
    }
    fmt.Println(array)
}

मैं उम्मीद कर रहा था कि अंतिम पंक्ति [[1,2,3], [0,5,4], [9,7,1], [0,2,8]] प्रिंट करेगी, हालांकि, मेरे आश्चर्य के लिए यह [[0 2 8] [0 2 8] [0 2 8] [0 2 8]], या [[9 7 1] [9 7 1] [9 7 1] [9 7 1]], या कुछ अन्य भिन्नताओं को प्रिंट करता है जिसमें कई बार केवल एक कुंजी होती है।

मेरा गो संस्करण 1.16.5 है

-3
lajosdeme 12 जुलाई 2021, 19:50

2 जवाब

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

फॉर-लूप में, लूप वेरिएबल्स को प्रत्येक पुनरावृत्ति पर ओवरराइट किया जाता है। अर्थात्, val एक सरणी है, और प्रत्येक पुनरावृत्ति के लिए, val की सामग्री को मानचित्र में अगले आइटम के साथ अधिलेखित कर दिया जाता है। चूंकि आपने स्लाइस जोड़े हैं (जो केवल एक सरणी पर देखे जाते हैं), सभी स्लाइस में val बैकिंग ऐरे के रूप में होते हैं, और उन सभी में समान सामग्री होती है, अर्थात्, जो भी अंतिम तत्व पुनरावृत्त होता है।

ठीक करने के लिए, सरणी की प्रतिलिपि बनाएँ:

    for val := range myMap {
        val:=val
        array = append(array, val[:])
    }
2
Burak Serdar 12 जुलाई 2021, 16:57

आप हर बार लूप इटरेटर वैरिएबल जोड़ रहे हैं, जो प्रत्येक पुनरावृत्ति को अपडेट किया जाता है। आपको इसके बजाय स्थानीय रूप से स्कोप की गई प्रतिलिपि जोड़ने की आवश्यकता है:

for val := range myMap {
    v := val
    array = append(array, v[:])
}
2
Adrian 12 जुलाई 2021, 16:57