2012-08-04 23 views
42

इस तरह एक struct बनाने के बाद:गोलांग structs में फ़ील्ड सेट और कैसे प्राप्त करें?

type Foo struct { 
    name string   

} 
func (f Foo) SetName(name string){ 
    f.name=name 
} 

func (f Foo) GetName string(){ 
    return f.name 
} 

मैं फू का एक नया उदाहरण कैसे बना सकते हैं और सेट और नाम मिलता है? मैं निम्नलिखित की कोशिश की:,

p:=new(Foo) 
p.SetName("Abc") 
name:=p.GetName() 
fmt.Println(name) 

कुछ भी नहीं मुद्रित हो जाता है क्योंकि नाम रिक्त है। तो मैं एक संरचना के अंदर एक क्षेत्र कैसे सेट और प्राप्त कर सकते हैं?

उत्तर

89

टीका (और काम) उदाहरण:

package main 

import "fmt" 

type Foo struct { 
    name string 
} 

// SetName receives a pointer to Foo so it can modify it. 
func (f *Foo) SetName(name string) { 
    f.name = name 
} 

// Name receives a copy of Foo since it doesn't need to modify it. 
func (f Foo) Name() string { 
    return f.name 
} 

func main() { 
    // Notice the Foo{}. The new(Foo) was just a syntactic sugar for &Foo{} 
    // and we don't need a pointer to the Foo, so I replaced it. 
    // Not relevant to the problem, though. 
    p := Foo{} 
    p.SetName("Abc") 
    name := p.Name() 
    fmt.Println(name) 
} 

Test it और ले A Tour of Go तरीकों और संकेत दिए गए, और सब पर जाओ की मूल बातें के बारे में अधिक जानने के लिए।

+14

नाम() गेटर के लिए मूर्खतापूर्ण नाम होगा (http://golang.org/doc/effective_go.html#Getters देखें) –

+1

यह स्वीकार्य उत्तर होना चाहिए! –

+0

@ अज्ञात आप सही हैं, मैंने जवाब संपादित किया। –

4

उदाहरण के लिए,

package main 

import "fmt" 

type Foo struct { 
    name string 
} 

func (f *Foo) SetName(name string) { 
    f.name = name 
} 

func (f *Foo) Name() string { 
    return f.name 
} 

func main() { 
    p := new(Foo) 
    p.SetName("Abc") 
    name := p.Name() 
    fmt.Println(name) 
} 

आउटपुट:

Abc 
+1

तकनीकी रूप से आपका उत्तर काम करेगा, GetFoo() Foo में Go के लिए idiomatic getter नामकरण नहीं है: यह केवल Foo() होना चाहिए। ज़िप्पोक्सर के उत्तर में अधिक जानकारी। – FGM

+1

यह एक अच्छा उदाहरण है, लेकिन 'GetName()' विधि के लिए आपको इसे पॉइंटर 'func (f * foo) द्वारा पास करने की आवश्यकता नहीं है, आपको' func (f foo) 'के साथ ठीक होना चाहिए क्योंकि आप' उस मान को संशोधित करें जिसे आपने अभी पढ़ा/वापस कर दिया है। –

+0

@ होनीर: "चुनौतियों पर मूल्य या सूचक रिसीवर का उपयोग करना चुनना मुश्किल हो सकता है, खासकर नए गो प्रोग्रामर के लिए। यदि संदेह है, तो एक सूचक का उपयोग करें।" [रिसीवर प्रकार, जाओ कोड समीक्षा टिप्पणियां] (https://github.com/golang/go/wiki/CodeReviewComments#receiver-type)। यह एक संक्षिप्त उदाहरण है, हम नहीं जानते कि वास्तविक संरचना कितनी बड़ी होगी। इसलिए, हम एक सूचक का उपयोग करते हैं। – peterSO

22

Setters और ही टिककर खेल नहीं कि जाने के लिए मुहावरेदार है। विशेष रूप से के लिए एक क्षेत्र एक्स गेटर GetX नाम नहीं है लेकिन सिर्फ एक्स http://golang.org/doc/effective_go.html#Getters

देखें सेटर विशेष तर्क प्रदान नहीं करता है, उदाहरण के लिए सत्यापन तर्क, फ़ील्ड को निर्यात करने में कोई गड़बड़ नहीं है और न ही एक सेटटर प्रदान करना और न ही गेटर विधि प्रदान करना। (यह जावा पृष्ठभूमि वाले किसी के लिए गलत लगता है। लेकिन यह नहीं है।)

+11

सूचना छिपाने के लिए कारणों का एक हिस्सा (encapsulation) प्रोग्राम विकास है। आप सीधे अपने कोड को सीधे पहुंच के साथ विभाजित नहीं करते हैं। आइए 1 साल बाद कहें, आप प्रमाणीकरण या कुछ अलग करने के लिए कुछ भी लागू करने का निर्णय लेते हैं। आप हजारों अलग-अलग स्थानों को दोबारा नहीं बदलना चाहते हैं, बल्कि सिर्फ एक फ़ाइल और एक ही स्थान पर। स्थापित प्रथाओं को फेंकना और अन्य भाषाओं से सोचा हमेशा सही काम नहीं है। – sat

+1

@sat अगर आपको हजारों स्थानों को दोबारा करना है, तो शायद आप पहले कुछ गलत कर रहे हैं। – Profpatsch

+4

@sat (और सभी अपवित्र): गो में कई हज़ार कॉल साइट्स को पुन: सक्रिय करना जटिल नहीं है। जी अभी भी मौजूद है और अन्य उपकरण तेजी से परिपक्व हो रहे हैं। कम से कम नहीं: केवल सभी एक्सेसों को लपेटना क्योंकि आप इस एक्सेस को बदलना चाहते हैं यागनी का उल्लंघन करते हैं और केवल तभी मदद करते हैं जब आप ** रिफैक्टरिंग कर सकते हैं ** ** केवल गेटटर को बदलकर किया जा सकता है (कोई अतिरिक्त त्रुटि केस नहीं, कोई अन्य रिफैक्टरिंग नहीं)। मैंने इस तरह के तर्कों को बहुत बार सुना है। यदि एपीआई अच्छी तरह डिज़ाइन की गई है तो आपको इन समस्याओं का सामना नहीं करना पड़ेगा और यदि एपीआई खराब है तो वैसे भी आपका खो गया है। – Volker