गोलंग क्यों हम एक सेट डेटास्ट्रक्चर नहीं है [बंद]


129

मैं "गो प्रोग्रामिंग लैंगैगेज" व्यायाम # 1.4 को हल करने की कोशिश कर रहा हूं जिसके लिए मुझे एक सेट की आवश्यकता है। मैं एक सेट प्रकार बना सकता हूं लेकिन भाषा एक के साथ क्यों नहीं आती है? गो, गूगल से आया है, जहां अमरूद की भी उत्पत्ति हुई है, भाषा डिजाइनरों ने मूलभूत डेटा संरचनाओं के लिए समर्थन जोड़ने का विकल्प क्यों नहीं चुना? क्यों अपने उपयोगकर्ताओं को एक सेट के रूप में कुछ बुनियादी के लिए अपने स्वयं के कार्यान्वयन बनाने के लिए मजबूर करें?


11
हममम। नकारात्मक वोट क्यों सोच रहे हैं? मैं जावा दुनिया से आ रहा हूं, जहां हमारे पास शुरू से ही लगभग एक सेट था, यहां तक ​​कि जेनरिक के बिना भी। इसलिए, मुझे यह व्यवहार एक अजीब विचित्र लगता है
अंजन

जवाबों:


83

आंशिक रूप से, क्योंकि गो में जेनरिक नहीं है (इसलिए आपको हर प्रकार के लिए एक सेट-प्रकार की आवश्यकता होगी, या प्रतिबिंब पर वापस गिरना होगा, जो कि अक्षम है)।

आंशिक रूप से, क्योंकि यदि आप सभी की जरूरत है "अलग-अलग तत्वों को एक सेट में जोड़ें / निकालें" और "अपेक्षाकृत स्थान-कुशल", तो आप बस एक का उपयोग करके map[yourtype]bool(और सेट में trueकिसी भी तत्व के लिए मूल्य निर्धारित कर सकते हैं) ) या, अधिक स्थान दक्षता के लिए, आप एक खाली संरचना का उपयोग मूल्य के रूप में कर सकते हैं और _, present = the_setoid[key]उपस्थिति की जांच के लिए उपयोग कर सकते हैं।


1
इसके अलावा, गो की आत्मा में यह लगता है कि इसे केवल अपने कोड में लिखें, या तो दूसरे कोड में सेट को "इनलाइन" करके या जरूरत पड़ने पर अपने खुद के सेट प्रकार को परिभाषित करें। वैसे भी, उदाहरण के लिए C ++ में एक सेट :: सेट <T> का उपयोग हमेशा फ़ंक्शन के कार्यान्वयन या कुछ अन्य डेटा संरचना को लागू करने के हिस्से के रूप में हो रहा है। इसलिए, केवल नक्शे और स्लाइस और जो भी अन्य बिल्डिंग ब्लॉक्स की आवश्यकता है, का उपयोग करके सीधे अन्य डेटा संरचना को लागू करें, लेकिन बिना किसी बिल्टिन सेट के। एक सेट का प्रत्येक उपयोग इसे वैसे भी थोड़ा अलग तरीके से उपयोग करने जा रहा है :)
Bjarke Ebert

1
लेकिन आम तौर पर आपको वास्तव में एक सेट <Foo> की आवश्यकता नहीं होती है, आप कुछ बड़ा लागू करने के हिस्से के रूप में एक सेट <Foo> का उपयोग करते हैं। मैंने कई टन कोड देखे हैं जहां "पुन: प्रयोज्य" घटक को शामिल करने के लिए आपको जो चीजें करने की आवश्यकता होती है, वह केवल आवश्यकता को टालने से बहुत खराब है। तो यहाँ हमारे पास एक सेट <Foo> है, उस फ़ंक्शन को वहां एक सेट की आवश्यकता है <Bar>, उफ़, क्या हमारे पास अभी तक सहसंयोजक हैं, या कैसे इस चीज़ को इस तरह दिखने के लिए एक WrapperFactory बनाने के बारे में, आदि। शायद अन्य फ़ंक्शन वास्तव में सिर्फ एक इंटरफ़ेस की आवश्यकता है जो सदस्यता के लिए जांच कर सकता है, इसलिए इसे सेट न करें <Foo>।
Bjarke Ebert

42
तो अगर यह जेनरिक नहीं है, तो 'जेनेरिक' नक्शा कैसे लागू किया जाता है?
फरमिन सिल्वा

26
ध्यान दें कि यदि आप बाइट्स सहेजना चाहते हैं, तो आप map[T]struct{}इसके बजाय उपयोग कर सकते हैं map[T]bool
प्रकट होना


69

एक कारण यह है कि मानचित्र से एक सेट बनाना आसान है:

s := map[int]bool{5: true, 2: true}
_, ok := s[6] // check for existence
s[8] = true // add element 
delete(s, 2) // remove element

संघ

s_union := map[int]bool{}
for k, _ := range s1{
    s_union[k] = true
}
for k, _ := range s2{
    s_union[k] = true
}

चौराहा

s_intersection := map[int]bool{}
for k,_ := range s1 { 
  if s2[k] {
    s_intersection[k] = true
  }
}

यह वास्तव में अन्य सभी सेट संचालन को लागू करने के लिए कठिन नहीं है।


10
अस्तित्व के लिए जाँच करें बस मानचित्र अनुक्रमणिका है। चूंकि अगर यह इसमें नहीं है, तो शून्य मान (जो है false) ठीक से बताएगा। परीक्षण के लिए अल्पविराम-मुहावरे की आवश्यकता नहीं है।
आईसीजे

2
अंतर के लिए कार्यान्वयन अंतर की तरह दिखता है।
मुशफिल

1
@ किट्सिल आपको धन्यवाद। अपडेट किया गया।
साल्वाडोर डाली

34
यह map[int]struct{}इसके बजाय उपयोग करने के लिए अधिक इष्टतम है bool, क्योंकि एक खाली संरचना मेमोरी में 0 बाइट्स का कब्जा करती है। मैंने हाल ही में इस gist.github.com/bgadrian/cb8b9344d9c66571ef331a14eb7a2e80 के
BG Adrian

13
यह इतना आसान नहीं है। बस उस कोड को हर जगह लिखने के लिए आपको एक सेट का उपयोग करने की आवश्यकता है जो इन दिनों मेरे लिए हास्यास्पद है। किसी भी भाषा द्वारा सामूहिक समर्थन प्रदान किया जाना चाहिए। एक बेहतर जवाब है कि गो अभी तक परिपक्व नहीं है। मुझे यकीन है कि जल्द ही इसे कवर करने के लिए पुस्तकालय होंगे।
स्टेफ

5

जैसे वैटाइन ने लिखा: चूँकि जाने वाले लोगों में जेनेरिक की कमी होती है, इसलिए इसे भाषा का हिस्सा होना चाहिए, न कि मानक पुस्तकालय। उसके लिए आपको तब कीवर्ड सेट, यूनियन, चौराहे, अंतर, सब्मिट के साथ भाषा को प्रदूषित करना होगा ...

दूसरा कारण यह है कि यह स्पष्ट नहीं है कि किसी सेट का "सही" कार्यान्वयन क्या है:

  1. एक कार्यात्मक दृष्टिकोण है:

    func IsInEvenNumbers(n int) bool {
        if n % 2 == 0 {
            return true
        }
       return false
    }

यह भी सभी ints का एक सेट है। इसकी एक बहुत ही कुशल खोज है और कार्यात्मक संरचना द्वारा संघ, अंतर, अंतर और सबसेट आसानी से किया जा सकता है।

  1. या आप है जैसे कि डाली ने दिखाया है।

एक मानचित्र में वह समस्या नहीं होती है, क्योंकि आप मूल्य से जुड़ी किसी चीज़ को संग्रहीत करते हैं।


2
बाइट-इन सेट्स को संभालने के लिए, पास्कल बाइनरी (दो-आर्ग्मेंट) ऑपरेटरों के एक समूह को ओवरलोड करता है: +संघ के लिए, -अंतर के लिए, अंतर के *लिए, <=सबसेट के लिए, सबसेट के लिए, >=सुपरसेट के लिए, =समानता के लिए, <>असमानता के लिए और inसदस्यता के लिए। जाओ में इसलिए, यह केवल एक ही नए कीवर्ड होगा - in। दूसरी ओर, पास्कल के निर्मित सेट केवल "ऑर्डिनल्स" पर काम करते हैं - अर्थात, किसी भी प्रकार जिसमें किसी आकार के पूर्णांक मान का अंतर्निहित प्रतिनिधित्व होता है।
kostix

9
यह तथ्य कि एक सेट को लागू करने के कई तरीके हैं, कई अन्य भाषाओं को उन्हें प्रदान करने से नहीं रोका गया है।
अगस्तुर

@kostix: गो सिंटैक्स का उपयोग भी कर सकते हैं s[key](जैसे कि अगर sथे map[T]bool) इसके बजाय key in s

2
बस वापस नहीं आने का कोई कारण n % 2 == 0?
जोहो एंड्रेड

4

एक अन्य संभावना बिट सेट का उपयोग करना है, जिसके लिए कम से कम एक पैकेज है या आप बिल्ट-इन बड़े पैकेज का उपयोग कर सकते हैं । इस मामले में, मूल रूप से आपको अपनी वस्तु को एक इंडेक्स में बदलने का एक तरीका परिभाषित करना होगा।


1
मुझे ध्यान देना चाहिए कि मैंने ऊपर संदर्भित बिटसेट पैकेज का मूल संस्करण लिखा था।
विल फिजराल्ड़
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.