खाली स्लाइस को इनिशियलाइज़ करने का सही तरीका


227

एक खाली स्लाइस को गैर-निश्चित आकार के साथ घोषित करने के लिए, क्या यह करना बेहतर है:

mySlice1 := make([]int, 0)

या:

mySlice2 := []int{}

बस सोच रहा था कि कौन सा सही तरीका है।


2
आप कहते हैं "गैर-निश्चित आकार", लेकिन स्लाइस का कभी निश्चित आकार नहीं होता है। जब तक आप शून्य क्षमता से मतलब नहीं रखते। ध्यान दें, यदि आपके पास एक विचार / अनुमान / संकेत है कि आपको किस क्षमता की आवश्यकता हो सकती है तो तीन तर्क संस्करण का उपयोग करना अच्छा है। उदाहरण के लिए चाबी का एक स्लाइस बनाने के लिए:keys := make([]int, 0, len(m)); for k, v := range m { keys := append(keys,k) }
डेव सी

जवाबों:


272

आपके द्वारा दिए गए दो विकल्प शब्दार्थ समान हैं, लेकिन उपयोग make([]int, 0)करने से runtime.makeslice के लिए एक आंतरिक कॉल होगा (1.14 जाओ)।

आपके पास इसे एक nilमूल्य के साथ छोड़ने का विकल्प भी है :

var myslice []int

जैसा कि गोलांग में लिखा गया है। ब्लॉग :

एक शून्य स्लाइस कार्यात्मक रूप से शून्य-लंबाई वाले स्लाइस के बराबर है, भले ही यह कुछ भी न हो। इसकी लंबाई शून्य है और इसे आवंटन के साथ जोड़ा जा सकता है।

एक nilस्लाइस हालांकि json.Marshal()में होगा, "null"जबकि एक खाली स्लाइस मार्शल होगा "[]", जैसा कि @farwayer द्वारा बताया गया है।

उपरोक्त विकल्पों में से कोई भी @ArmanOrdookhani द्वारा इंगित किए गए किसी भी आवंटन का कारण नहीं होगा।



106
ध्यान रखें: प्रारंभिक स्लाइस के लिए और json.Marshal()फिर से लौटेंगेnullvar myslice []int[]myslice := []int{}
23

10
इसके अलावा सावधान रहें: reflect.DeepEqualशून्य स्लाइस और गैर शून्य स्लाइस के बीच एक अंतर बना देता है: a := []int{}, var b []int,reflect.DeepEqual(a, b) // returns false
asgaines

1
आपको क्यों लगता है कि यह एक आवंटन करेगा? कैप शून्य है इसलिए कुछ भी आवंटित नहीं किया गया है। सभी शून्य लंबाई की बातें स्मृति में एक ही स्थान पर इंगित करती हैं: play.golang.org/p/MPOKKl_sYvw
अरमान आयुधानी

1
@ArmanOrdookhani आप सही हैं। मैंने इसे आज़माया, और मुझे यह भी पता चला कि मैं समान विधानसभा निर्देशों पर अपनी धारणा के साथ गलत था। फिक्स्ड!
एनिसस

65

वे बराबर हैं। इस कोड को देखें:

mySlice1 := make([]int, 0)
mySlice2 := []int{}
fmt.Println("mySlice1", cap(mySlice1))
fmt.Println("mySlice2", cap(mySlice2))

आउटपुट:

mySlice1 0
mySlice2 0

दोनों स्लाइस की 0क्षमता है, जिसका अर्थ है कि दोनों स्लाइस की 0लंबाई (क्षमता से अधिक नहीं हो सकती) जिसका अर्थ है कि दोनों स्लाइस में कोई तत्व नहीं है। इसका मतलब है कि 2 स्लाइस हर पहलू में समान हैं।

ऐसे ही सवाल देखें:

गोल गाल में नील का टुकड़ा और खाली टुकड़ा होने का क्या मतलब है?

शून्य स्लाइस बनाम गैर-शून्य स्लाइस बनाम गो भाषा में खाली स्लाइस


46

@ANisus के उत्तर के अतिरिक्त ...

नीचे "गो इन एक्शन" पुस्तक से कुछ जानकारी है , जो मुझे लगता है कि ध्यान देने योग्य है:

अंतर nilऔर emptyस्लाइस

अगर हम इस तरह एक टुकड़ा के बारे में सोचते हैं:

[pointer] [length] [capacity]

फिर:

nil slice:   [nil][0][0]
empty slice: [addr][0][0] // points to an address

नील का टुकड़ा

वे उपयोगी होते हैं जब आप एक स्लाइस का प्रतिनिधित्व करना चाहते हैं जो मौजूद नहीं है, जैसे कि जब एक फ़ंक्शन में कोई अपवाद होता है जो एक स्लाइस देता है।

// Create a nil slice of integers.
var slice []int

खाली टुकड़ा

खाली स्लाइस तब उपयोगी होते हैं जब आप एक खाली संग्रह का प्रतिनिधित्व करना चाहते हैं, जैसे कि जब डेटाबेस क्वेरी शून्य परिणाम देता है।

// Use make to create an empty slice of integers.
slice := make([]int, 0)

// Use a slice literal to create an empty slice of integers.
slice := []int{}

भले ही आपको नहीं के बराबर टुकड़ा या एक खाली टुकड़ा, बिल्ट-इन कार्य उपयोग कर रहे हैं की append, lenऔर capकाम एक ही।


खेल के मैदान का उदाहरण देखें :

package main

import (
    "fmt"
)

func main() {

    var nil_slice []int
    var empty_slice = []int{}

    fmt.Println(nil_slice == nil, len(nil_slice), cap(nil_slice))
    fmt.Println(empty_slice == nil, len(empty_slice), cap(empty_slice))

}

प्रिंट:

true 0 0
false 0 0

क्या हम एक कदम में खाली स्लाइस का पता प्राप्त कर सकते हैं make?
सिमिन जी

यदि हम फ़ंक्शन हस्ताक्षर पर एक नज़र डालते हैं , makeतो पता वापस नहीं लगता है। मेरा मानना ​​है कि आप इसे एक चरण में नहीं कर सकते।
tgogos

13

खाली स्लाइस और नील स्लाइस को गो में अलग-अलग तरीके से इनिशियलाइज़ किया जाता है:

var nilSlice []int 
emptySlice1 := make([]int, 0)
emptySlice2 := []int{}

fmt.Println(nilSlice == nil)    // true
fmt.Println(emptySlice1 == nil) // false
fmt.Println(emptySlice2 == nil) // false

सभी तीन स्लाइस के लिए, लेन और कैप 0 हैं।


make([]int, 0)सबसे अच्छा है क्योंकि Jetbrains GoLand इसे "अनावश्यक" होने के बारे में शिकायत नहीं करता है क्योंकि यह मामले में करता है []int{}। यह इकाई परीक्षण लिखने में उपयोगी है।
आंद्रेजेज रहमान
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.