2014-06-30 9 views
30

"unexported क्षेत्र या विधि का उल्लेख नहीं कर सकते हैं" मैं इस तरह एक golang संरचना कुछ है:आह्वान golang struct समारोह देता

type MyStruct struct { 
    Id string 
} 

और समारोह:

func (m *MyStruct) id() { 
    // doing something with id here 
} 

इसके अलावा, मैं इस तरह एक और संरचना है :

:

type MyStruct2 struct { 
    m *MyStruct 
} 

अब मैं एक समारोह है

func foo(str *MyStruct2) { 
    str.m.id() 
} 

लेकिन मैं संकलन समय में त्रुटि मिल रही है:

str.m.id undefined (cannot refer to unexported field or method mypackage.(*MyStruct)."".id 

मैं इस समारोह को सही ढंग से कॉल कर सकते हैं?

आप

उत्तर

66

धन्यवाद http://golang.org/ref/spec#Exported_identifiers से:

एक पहचानकर्ता एक और पैकेज से उस तक पहुँच की अनुमति के लिए निर्यात किया जा सकता है। एक पहचानकर्ता दोनों अगर निर्यात किया जाता है:

  1. पहचानकर्ता के नाम का पहला वर्ण कोई यूनिकोड अपर केस पत्र (यूनिकोड वर्ग "लू") है; और
  2. पहचानकर्ता पैकेज ब्लॉक में घोषित किया गया है या यह एक फ़ील्ड नाम या विधि का नाम है।

तो मूल रूप से केवल कार्य/चर बड़े अक्षर से शुरू होने वाले पैकेज के बाहर प्रयोग करने योग्य हो जाएगा।

उदाहरण:

type MyStruct struct { 
    id string 
} 

func (m *MyStruct) Id() { 
    // doing something with id here 
} 

//then 

func foo(str *MyStruct2) { 
    str.m.Id() 
} 
+9

इस च ** राजा बात है! 'इसलिए मूल रूप से केवल --- पूंजी पत्र --- से शुरू होने वाले फ़ंक्शंस/वेरिएबल' के बाहर उपयोग योग्य होंगे। धन्यवाद! –

+1

यह मजाकिया है कि इस बारे में कोई अन्य पोस्ट कैसे नहीं है। वे सभी इस समस्या को बाईपास करने के विभिन्न तरीकों का प्रस्ताव देते हैं। धन्यवाद। – rottenoats

+1

हां, यह निश्चित रूप से उत्तर – alisa

2

आप MyStruct.IdMyStruct.id लिए, आप अब, MyStruct2 प्रारंभ करने में इसे उपयोग करने में सक्षम हो जाएगा, क्योंकि id केवल अपने स्वयं के पैकेज से पहुँचा जा सकेगा बदलते हैं (जो first है पैकेज)।

ऐसा इसलिए है क्योंकि MyStruct और MyStruct2 विभिन्न पैकेजों में हैं।


हल करने के लिए आप यह कर सकते हैं कि:

पैकेज first:

package first 

type MyStruct struct { 
    // `id` will be invisible outside of `first` package 
    // because, it starts with a lowercase letter 
    id string 
} 

// `Id()` is visible outside to `first` package 
// because, it starts with an uppercase letter 
func (m *MyStruct) Id() string { 
    return m.id 
} 

// Create a constructor function to return `*MyStruct` 
func NewMyStruct(id string) *MyStruct { 
    return &MyStruct{ 
     id: id, 
    } 
} 

पैकेज second:

package second 

// Import MyStruct's package 
import "first" 

type MyStruct2 struct { 
    // If you don't use `m` here as in your question, 
    // `first.MyStruct` will be promoted automatically. 
    // 
    // So, you can reach its methods directly, 
    // as if they're inside `MyStruct2` 
    *first.MyStruct 
} 

// You can use `Id()` directly because it is promoted 
// As if, inside `MyStruct2` 
func foo(str *MyStruct2) { 
    str.Id() 
} 

// You can initialize `MyStruct2` like this: 
func run() { 
    foo(&MyStruct2{ 
     MyStruct: first.NewMyStruct("3"), 
    }) 
}