स्लाइस की घोषणा करें या स्लाइस बनाएं?


99

जाओ में, के बीच अंतर क्या है var s []intऔर s := make([]int, 0)?

मुझे लगता है कि दोनों काम करते हैं, लेकिन कौन सा बेहतर है?


पहला एक nilस्लाइस बनाता है , जबकि दूसरा एक emptyस्लाइस बनाता है (यह "एक्शन बुक में जाओ" ) द्वारा प्रयुक्त शब्दावली है । यहाँ भी एक ही उत्तर पोस्ट करने से बचने के लिए, आप stackoverflow.com/a/45997533/1561148
tgogos

जवाबों:


95

फेब्रिआज़ोम के उत्तर के अलावा , आप " गो स्लाइस: यूज़ एंड इंटर्नल " पर और अधिक उदाहरण देख सकते हैं , जहाँ उपयोग के लिए []intउल्लेख किया गया है:

चूंकि एक स्लाइस का शून्य मान ( nil) शून्य-लंबाई वाले स्लाइस की तरह काम करता है , आप स्लाइस वेरिएबल की घोषणा कर सकते हैं और फिर इसे लूप में जोड़ सकते हैं:

// Filter returns a new slice holding only
// the elements of s that satisfy f()
func Filter(s []int, fn func(int) bool) []int {
    var p []int // == nil
    for _, v := range s {
        if fn(v) {
            p = append(p, v)
        }
    }
    return p
}

इसका मतलब है कि, एक टुकड़ा करने के लिए संलग्न करने के लिए, आप पहली बार स्मृति को आबंटित करने की जरूरत नहीं है: nilटुकड़ा p int[]के रूप में एक टुकड़ा में जोड़ने के लिए पर्याप्त है।


आपको क्यों लगता है कि यह एक आवंटन करेगा? कैप शून्य है इसलिए कुछ भी बिना या उसके बिना आवंटित नहीं किया गया है।
अरमान आयुधानी

1
@ArmanOrdookhani सहमत मैं सिर्फ घोषणा var p []intका उपयोग करने की तुलना में आसान पाता हूं make(जो कि मैं आवंटन के साथ अधिक संबद्ध हूं, भले ही 0 कैप के साथ, यह कुछ भी आवंटित नहीं करेगा)। पठनीयता के संदर्भ में, मैं makeयहां प्रयोग नहीं करना पसंद करता हूं ।
VonC

1
मैं हर जगह (जैसे p := []int{}) शाब्दिक का उपयोग करने की ओर अधिक हूं । चूंकि हम आमतौर पर :=सबसे अधिक चर घोषित करने के लिए सिंटैक्स का उपयोग करते हैं, इसलिए स्लाइस के लिए अपवाद होने के बजाय हर जगह ऐसा होना स्वाभाविक है। इसके अलावा आवंटन के बारे में सोचने की कोशिश आमतौर पर लोगों को समय से पहले अनुकूलन की ओर धकेलती है।
अरमान आयुधानी

113

सरल घोषणा

var s []int

जबकि स्मृति और sअंक आवंटित नहीं करता हैnil

s := make([]int, 0)

स्मृति को आवंटित करता है और s0 तत्वों के साथ एक टुकड़ा करने के लिए स्मृति को इंगित करता है।

यदि आप अपने उपयोग के मामले का सटीक आकार नहीं जानते हैं, तो आमतौर पर पहले वाला अधिक मुहावरेदार होता है।


क्या मैं नक्शे के लिए भी ऐसा ही कह सकता हूं? var m map [string] int vs m: = make (नक्शा [स्ट्रिंग] int)? धन्यवाद।
जोशुआ

11
नाह, आपको makeनक्शों की जरूरत है , क्योंकि mapकुछ बहीखाते के लिए भी खाली जगह की जरूरत होती है।
twotwotwo

11
यदि आपको 0 तत्वों ('शून्य' के बजाय) के साथ एक टुकड़ा वापस करने की आवश्यकता है, तो सही उपयोग है।
जेस

6
यदि आप एक एपीआई का निर्माण कर रहे हैं और प्रतिक्रिया के रूप में एक सरणी लौटाते हैं nil, तो एक खाली सरणी के बजाय आपके स्लाइस में कोई तत्व नहीं होने की स्थिति में , घोषणात्मक रूप का उपयोग करके वापस आ जाएगा । हालांकि, यदि makeस्लाइस बनाने के लिए उपयोग किया जाता है , तो इसके बजाय एक खाली सरणी वापस आ जाएगी, जो आमतौर पर वांछित प्रभाव है।
रॉबिनमित्र

6
जैसा कि इस उत्तर पर एक टिप्पणी में उल्लेख किया गया है: stackoverflow.com/a/29164565/1311538 , json marshaling जैसी चीजों को करने का प्रयास करते समय मतभेद होते हैं। शून्य टुकड़ा (मार्शलिंग var s []int) का उत्पादन करेगा null, जबकि खाली टुकड़ा (प्रमुखता s := make([]int, 0)) की उम्मीद उत्पादन करेगा[]
asgaines

8

बस एक अंतर मिला। यदि तुम प्रयोग करते हो

var list []MyObjects

और फिर आप JSON के रूप में आउटपुट को एन्कोड करते हैं, आपको मिलता है null

list := make([]MyObjects, 0)

[]उम्मीद के मुताबिक परिणाम आए ।


हाँ, बाद में काफी उपयोगी है जब हम अशक्त के बजाय [] सरणी के साथ प्रतिक्रिया करना चाहते हैं
नाहन ट्रान

4

थोड़ा और पूरी तरह से (एक और तर्क में make) उदाहरण:

slice := make([]int, 2, 5)
fmt.Printf("length:  %d - capacity %d - content:  %d", len(slice), cap(slice), slice)

बाहर:

length:  2 - capacity 5 - content:  [0 0]

या गतिशील प्रकार के साथ slice:

slice := make([]interface{}, 2, 5)
fmt.Printf("length:  %d - capacity %d - content:  %d", len(slice), cap(slice), slice)

बाहर:

length:  2 - capacity 5 - content:  [<nil> <nil>]

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