2015-08-25 8 views
6

जब एक साधारण वस्तु का निर्माण करते हैं, तो इन विकल्पों के बीच क्या अंतर होता है?गो कन्स्ट्रक्टर में वापसी मूल्य बनाम सूचक

func NewGender(value string) Gender { 
    return Gender{strings.TrimSpace(value)} 
} 

func NewGender(value string) *Gender { 
    return &Gender{strings.TrimSpace(value)} 
} 
+0

यदि आप किसी अन्य कोड में '* लिंग 'पास करते हैं, तो यह इसे बदल सकता है। 'लिंग' के साथ ऐसा नहीं है। – twotwotwo

+3

संबंधित/डुप्लिकेट: [गो रिटर्न एड्रेस का कन्स्ट्रक्टर क्यों होना चाहिए?] (Http://stackoverflow.com/questions/31932822/why-should-constructor-of-go-return-address) – icza

+0

सवाल बिल्कुल सही नहीं है वही और मुझे लगता है कि @ एनार-जी उत्तर उस टिकाऊ डुप्लिकेट के लिए स्वीकार्य से बेहतर है –

उत्तर

7

प्रश्न वास्तव में एक व्यापक है, और यह आपके बाकी एपीआई पर भारी निर्भर करता है। तो यहाँ सिर्फ कुछ चीजें आप जब दूसरे पर एक को चुनने (किसी विशेष क्रम में) पर विचार करने की आवश्यकता हो सकती हैं:

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

  • पॉइंटर्स किसी चीज़ की उपस्थिति या अनुपस्थिति को भी संकेत दे सकते हैं, हालांकि इसके लिए अल्पविराम-ठीक मुहावरे का उपयोग करना बेहतर होता है, या कोई त्रुटि लौटाती है।

  • त्रुटियों की बात करते हुए, यदि आप nil को किसी त्रुटि के साथ लौटते हैं, तो त्रुटि को अनदेखा कर दिया जाएगा, क्योंकि शून्य पॉइंटर अव्यवस्था का परिणाम आतंक में होगा)। फिर फिर, मुझे नहीं लगता कि जो लोग त्रुटियों को अनदेखा करते हैं वे हैं जो आपको वास्तव में ध्यान में रखना चाहिए।

  • यदि आपको कुछ प्रकार की ट्रैकिंग की आवश्यकता है (उदाहरण के लिए, आपके कन्स्ट्रक्टर द्वारा बनाए गए सभी उदाहरणों का निरीक्षण करने की संभावना), तो आपको एक सूचक वापस करना होगा, ताकि मूल्य में सभी परिवर्तन इंस्पेक्टर को दिखाई देंगे।

  • यदि अधिकांश प्रकार के तरीकों में पॉइंटर रिसीवर होता है, या एपीआई में अधिकांश फ़ंक्शन मानकों के बजाय टाइप करने के लिए पॉइंटर्स स्वीकार करते हैं, तो यह पॉइंटर वापस करने के लिए अधिक ergonomic है।

2

लौटा पहला आइटम एक मूल्य है, दूसरा सूचक है। सूचक सी या सी ++ में पॉइंटर की तरह काम करता है, केवल उस मूल्य को इंगित करता है जो सी # या जावा में एकत्रित कचरा होता है। जाओ उन दो प्रतिमानों के बीच एक समझौता कुछ प्रदान करता है। सूचक स्पष्ट और उजागर है, हालांकि यह अभी भी कचरा एकत्रित है। यहां कुछ हद तक स्पष्ट मतभेद हैं;

1) यदि आप किसी विधि को मान पास करते हैं या यह रिसीवर (जो अक्सर भ्रमित होता है) तो आप इसके मूल्य को संशोधित करने में सक्षम नहीं होंगे, यह अन्य भाषाओं में 'मूल्य से गुजरना' होगा आप एक प्रति संशोधित कर रहे हैं। हां, यहां तक ​​कि विधि func (g Gender) ChangeGender() उस ऑब्जेक्ट का लिंग भी नहीं बदलेगा जिसे आप इसे कॉल करते हैं। https://play.golang.org/

2) आप केवल प्रकार के लिए परिभाषित विधियों को कॉल कर सकते हैं। उदाहरण के लिए यदि आपके पास g *Gender है और आप ऊपर ChangeGender विधि को कॉल करना चाहते हैं तो आप सी/सी ++ की तरह अपने सूचक को बिना किसी संदर्भ के सक्षम नहीं कर पाएंगे। इसके विपरीत विपरीत दिशा में चल रहा है।

3) मूल्य से गुजरने का विकल्प संदर्भ द्वारा है, आप शायद जानते हैं कि यह कैसे काम करता है लेकिन यदि आप नहीं समझेंगे तो मैं समझाऊंगा। यदि आपके पास func (g *Gender) ModifyGender() और एक उदाहरण g := &Gender{} है तो ModifyGender को कॉल करते समय ओएस 'शब्द आकार का सूचक पॉइंट को मूल्य के बजाए तर्क के रूप में धक्का दिया जाएगा और विधि उस स्मृति का उपयोग स्मृति को संशोधित करने के लिए करेगी, कॉलर पर नियंत्रण लौटने पर परिवर्तन होता है। यदि आपके पास ऐसी विधि है जो ऑब्जेक्ट्स पर काम करती है जिसमें बड़ी मेमोरी पैर प्रिंट है तो यह प्रदर्शन में काफी सुधार कर सकता है।

मैं प्रदर्शन से बात नहीं करने जा रहा हूं। इससे आपको यह समझने के लिए पर्याप्त जानकारी मिलनी चाहिए कि यह आपके आवेदन में कैसे काम करता है।

संबंधित मुद्दे