गो स्ट्रक्चर में डिफ़ॉल्ट मान कैसे सेट करें


143

नीचे दिए गए प्रश्न के कई उत्तर / तकनीक हैं:

  1. गोलांग संरचनाओं के लिए डिफ़ॉल्ट मान कैसे सेट करें?
  2. गोलंग में स्ट्रक्चर्स को इनिशियलाइज़ कैसे करें

मेरे पास कुछ उत्तर हैं लेकिन आगे चर्चा की आवश्यकता है।



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

यहां दो प्रश्न हैं, एक को चुनें। मान लें कि आप पहले प्रश्न के लिए चुनते हैं (प्रश्न शीर्षक के अनुसार), कृपया अपने पूर्व शोध के बारे में अधिक विशिष्ट रहें और जहां आपके अन्य उत्तरों के लिए अधिक चर्चा की आवश्यकता हो।
डंकन जोन्स

जवाबों:


96

एक संभावित विचार अलग कंस्ट्रक्टर फ़ंक्शन लिखना है

//Something is the structure we work with
type Something struct {
     Text string 
     DefaultText string 
} 
// NewSomething create new instance of Something
func NewSomething(text string) Something {
   something := Something{}
   something.Text = text
   something.DefaultText = "default text"
   return something
}

6
हां, यह उन तरीकों में से एक है जिसका मैंने अपने उत्तर में भी उल्लेख किया है लेकिन ऐसा कोई तरीका नहीं है जिससे हम किसी को केवल इस फ़ंक्शन का उपयोग करने के लिए मजबूर कर सकें।
प्रतीक

@Prateek यह या तो यह है या एक इंटरफ़ेस का उपयोग करता है, जो बदसूरत और अधूरा होगा।
OneOfOne

31
@Prateek हाँ, आप लोगों को इस कंस्ट्रक्टर का उपयोग करने के लिए बाध्य कर सकते हैं यदि आप केवल टाइप को ही अनएक्सपोर्ट करते हैं। आप फ़ंक्शन NewSomethingऔर यहां तक ​​कि फ़ील्ड्स Textऔर निर्यात कर सकते हैं DefaultText, लेकिन बस संरचना प्रकार निर्यात नहीं करते हैं something
अमित कुमार गुप्ता

1
समस्या और भी बदतर है ... यदि आपकी संरचना ( reflect.New()उदाहरण के लिए) के माध्यम से त्वरित करने के लिए किसी तीसरे पक्ष (पुस्तकालय, उदाहरण के लिए) का उपयोग किया जाता है , तो यह आपके विशेष रूप से नामित कारखाने फ़ंक्शन के बारे में जानने की उम्मीद नहीं की जा सकती है। उस मामले में, और भाषा की कमी से ही बदल रहा है, केवल एक इंटरफ़ेस (जो पुस्तकालय के लिए जाँच कर सकता है) करेगा, मुझे लगता है।
edam

1
डिफ़ॉल्ट सेट करना अच्छा है, लेकिन कभी-कभी, मैं डिफ़ॉल्ट को ओवरराइड करना चाह सकता हूं। इस स्थिति में, मैं एक ऐसे मूल्य के साथ एक संरचना को शुरू करने में सक्षम नहीं होगा जो डिफ़ॉल्ट नहीं है। मेरे लिए थोड़ा कष्टप्रद
जूलियात्ज़िन

68
  1. संरचना (कंस्ट्रक्टर तरीका) प्राप्त करने के लिए एक विधि को बाध्य करें।

    एक अच्छा डिजाइन अपने प्रकार को बिना लाइसेंस के बनाना है, लेकिन एक निर्यात किए गए निर्माण फ़ंक्शन जैसे न्यूमाइपे () को प्रदान करें जिसमें आप अपनी संरचना / प्रकार को ठीक से शुरू कर सकते हैं। एक इंटरफ़ेस प्रकार भी लौटाएं और एक ठोस प्रकार नहीं, और इंटरफ़ेस में वह सब कुछ होना चाहिए जो अन्य आपके मूल्य के साथ करना चाहते हैं। और आपके ठोस प्रकार को निश्चित रूप से उस इंटरफ़ेस को लागू करना चाहिए।

    यह केवल प्रकार को खुद को अप्रमाणित बनाने के द्वारा किया जा सकता है। आप फ़ंक्शन NewSomething और यहां तक ​​कि फ़ील्ड्स टेक्स्ट और डिफॉल्टट को निर्यात कर सकते हैं, लेकिन बस संरचना प्रकार कुछ निर्यात नहीं करते हैं

  2. डिफ़ॉल्ट मॉड्यूल (लिंक में विकल्प 5) सेट करने के लिए कॉन्फ़िगरेशन संरचना का उपयोग करके आपके लिए स्वयं के मॉड्यूल के लिए इसे अनुकूलित करने का एक और तरीका है, हालांकि एक अच्छा तरीका नहीं है।


7
यह अब एक टूटी हुई कड़ी है (404): joneisen.tumblr.com/post/53695478114/golang-and-default-values
विक्टर

3
यह Wayback मशीन में उपलब्ध है ।
n8henrie

एफडब्ल्यूआईडब्ल्यू, मुझे लगता है कि यह 'विकल्प 3' है - कम से कम वेबैक मशीन लिंक में। (कोई 'विकल्प 5' नहीं है, वहां)।
डेसिमुस फोस्टल

@ m90 गॉलिंट को आप सार्वजनिक इंटरफ़ेस प्रकार लौटाने के रूप में अपने कार्य की घोषणा कर सकते हैं
थॉमस

@ThomasGrainger मेरी टिप्पणी इस उत्तर के पिछले संशोधन का जिक्र करती है, यह वास्तव में इस तरह का कोई मतलब नहीं है :) मैं अभी इसे हटा दूंगा।
m90

32

विक्टर ज़मानियन के उत्तर में विकल्प 1 के साथ एक समस्या यह है कि यदि प्रकार निर्यात नहीं किया जाता है, तो आपके पैकेज के उपयोगकर्ता इसे फ़ंक्शन मापदंडों के प्रकार के रूप में घोषित नहीं कर सकते हैं। इसके चारों ओर एक तरीका इसके बजाय एक इंटरफ़ेस निर्यात करना होगा संरचना जैसे

package candidate
// Exporting interface instead of struct
type Candidate interface {}
// Struct is not exported
type candidate struct {
    Name string
    Votes uint32 // Defaults to 0
}
// We are forced to call the constructor to get an instance of candidate
func New(name string) Candidate {
    return candidate{name, 0}  // enforce the default value here
}

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


नया फ़ंक्शन कॉल करने के बाद नाम और वोट चर बदलने के लिए उपलब्ध है?
मोर्टेजा खादम

अच्छा सरल उदाहरण है।

छोटे टाइपो: Votes unit32शायद होना चाहिएVotes uint32
पार्टीलिख

@PartyLich को अच्छी तरह से स्पॉट किया गया। तय होना चाहिए।
wolfson109

13

टैग के साथ ऐसा करने का एक तरीका है, जो कई चूक के लिए अनुमति देता है।

मान लें कि आपके पास निम्न संरचना है, जिसमें 2 डिफ़ॉल्ट टैग default0 और default1 हैं

type A struct {
   I int    `default0:"3" default1:"42"`
   S string `default0:"Some String..." default1:"Some Other String..."`
}

अब चूक को सेट करना संभव है।

func main() {

ptr := &A{}

Set(ptr, "default0")
fmt.Printf("ptr.I=%d ptr.S=%s\n", ptr.I, ptr.S)
// ptr.I=3 ptr.S=Some String...

Set(ptr, "default1")
fmt.Printf("ptr.I=%d ptr.S=%s\n", ptr.I, ptr.S)
// ptr.I=42 ptr.S=Some Other String...
}

यहाँ एक खेल के मैदान में पूरा कार्यक्रम है

यदि आप अधिक जटिल उदाहरण में रुचि रखते हैं, तो स्लाइस और नक्शे के साथ कहें, फिर, क्रीस्टी / डिफॉल्ट पर एक नज़र डालें


बहुत बहुत धन्यवाद! मैंने उसी कोड को लिखना शुरू किया, जैसा कि लाइब्रेरी ने सुझाया था और इस पोस्ट पर आया था। यह वही करता है जो आप उम्मीद करते हैं ( github.com/creasty/defaults )। यदि आपके पास कोई मान नहीं है, तो यह डिफ़ॉल्ट सेट करता है, लेकिन यदि आपने अपने चर के लिए मान निर्दिष्ट किया है, तो यह डिफ़ॉल्ट को असाइन नहीं करने वाला है। यह yaml.v2 लाइब्रेरी के साथ बहुत अच्छा काम करता है।
नॉर्ड्स

3

से https://golang.org/doc/effective_go.html#composite_literals :

कभी-कभी शून्य मान बहुत अच्छा नहीं होता है और एक प्रारंभिक निर्माता आवश्यक है, जैसा कि पैकेज ओएस से प्राप्त इस उदाहरण में है।

    func NewFile(fd int, name string) *File {
      if fd < 0 {
        return nil
      }
      f := new(File)
      f.fd = fd
      f.name = name
      f.dirinfo = nil
      f.nepipe = 0
      return f
}

-3
type Config struct {
    AWSRegion                               string `default:"us-west-2"`
}

1
यह गलत है। सर्वोत्तम रूप से, आप उस फ़ील्ड पर एक टैग मान सेट कर सकते हैं और फिर प्रतिबिंब के साथ उसके मूल्य पर पहुँच सकते हैं लेकिन यहां तक ​​कि इसके साथ वाक्यविन्यास गलत है (वापस टिक गायब) और आप केवल स्ट्रिंग प्रकार के लिए डिफ़ॉल्ट मान सेट करने में सक्षम होंगे। यदि आपके पास कुछ अंतर्दृष्टि है, तो यह उदाहरण विशेष रूप से संदर्भित करने के लिए कृपया एक लिंक जोड़ें।
markeissler
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.