2012-10-27 19 views
6

ऐसी कंपनी है, जो एक संरचना है, जिसमें व्यक्ति का नक्शा शामिल है, जो सभी structs भी हैं।मानचित्र में एक संरचना पर एक सूचक विधि को कॉल करना

type Company struct { 
    employees map[int]Person 
} 

type Person struct { 
    [...] 
} 

कुछ व्यक्तियों को कर्मचारियों-मानचित्र को आवंटित करने के बाद, मैं इनमें से प्रत्येक पर एक सूचक विधि कॉल करने की कोशिश कर रहा हूं।

func (company *Company) Populate(names []string) { 
    for i := 1; i <= 15; i++ { 
     company.employees[i] = Person{names[i - 1], [...]} 
     company.employees[i].Initialize() 
    } 
} 

यह बुरी तरह विफल रहता है, गो-संकलक शिकायत है कि मैं company.employees [i] पर सूचक तरीकों कॉल नहीं कर सकते हैं, साथ ही मैं company.employees का पता नहीं ले जा सकते के साथ [i]। हालांकि, एक गैर सूचक विधि को प्रारंभ-विधि की स्थापना और दे यह व्यक्ति की प्रतिलिपि वापसी , और

company.employees[i] = company.employees[i].Initialize() 

कार्यों का उपयोग, जो नहीं है कि द्वारा फिर से नक्शा को आवंटित विभिन्न।

पॉइंटर्स के साथ काम नहीं किया है, यह मुझे कभी भी बहुत खराब करता है। मानचित्र अपरिवर्तनीय नहीं हैं, और वे किसी भी तरह से संशोधित हो जाते हैं, इसलिए मानचित्र में किसी इकाई पर पॉइंटर विधि को कॉल करना कोई समस्या नहीं होनी चाहिए - कम से कम मेरे सिर में।

यदि कोई मुझे बता सकता है कि मैं यहां क्या कर रहा हूं - या मेरी सोच को सही करें - मुझे प्रसन्नता होगी।

उत्तर

11

समस्या यहां के लिए एक सूचक विधि कॉल करने में, employees[i] का पता ले जाने की आवश्यकता है। Go specification के अनुसार:

ऑपरेंड को एक परिवर्तनीय, सूचक संकेत, या स्लाइस इंडेक्सिंग ऑपरेशन होना चाहिए; या एक एड्रेसेबल स्ट्रक्चर ऑपरेंड का फील्ड चयनकर्ता; या एक एड्रेसेबल सरणी के एक सरणी अनुक्रमण ऑपरेशन। एड्रेसबिलिटी आवश्यकता के अपवाद के रूप में, एक्स एक समग्र शाब्दिक भी हो सकता है।

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

तो, आप इसे कैसे ठीक कर सकते हैं? यदि आपके पास map[int]*Person है, तो आपको मानचित्र में डेटा का पता लेने की आवश्यकता नहीं होगी क्योंकि नक्शा मान पहले से ही एक पता है।

सलाह का एक आखिरी बिट, Person.Initialize() बहुत मूर्खतापूर्ण गो कोड नहीं है। यदि आपको किसी प्रकार को प्रारंभ करने की आवश्यकता है, तो आप आमतौर पर NewPerson() फ़ंक्शन का उपयोग करते हैं। NewPerson() फ़ंक्शन प्रारंभिक व्यक्ति संरचना या सूचक वापस लौटाएगा।

+1

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

0

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

package main 

import "fmt" 

type Person struct { 
    Name string 
} 

func NewPerson(name string) *Person { 
    return &Person{Name: name} 
} 

type Company struct { 
    Employees map[int]*Person 
} 

func (c *Company) Populate(names []string) { 
    c.Employees = make(map[int]*Person) 
    for i := range names { 
     c.Employees[i+1] = NewPerson(names[i]) 
    } 
} 

func main() { 
    c := Company{} 
    c.Populate([]string{"Peter", "Paul"}) 
    for k, v := range c.Employees { 
     fmt.Println(k, *v) 
    } 
} 

आउटपुट:

1 {Peter} 
2 {Paul}