La función invoke golang struct da “no se puede referir al campo o método no exportado”

Tengo una estructura de golang algo como esto:

type MyStruct struct { Id string } 

y función:

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

También tengo otra estructura como esta:

 type MyStruct2 struct { m *MyStruct } 

Ahora tengo una función:

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

Pero recibo un error en tiempo de comstackción:

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

¿Cómo puedo llamar a esta función correctamente?

Gracias

De http://golang.org/ref/spec#Exported_identifiers :

Se puede exportar un identificador para permitir el acceso desde otro paquete. Un identificador se exporta si ambos:

  1. el primer carácter del nombre del identificador es una letra mayúscula Unicode (clase Unicode “Lu”); y
  2. el identificador se declara en el bloque de paquete o es un nombre de campo o un nombre de método.

Entonces, básicamente, solo las funciones / variables que comiencen con una letra mayúscula podrían usarse fuera del paquete.

Ejemplo:

 type MyStruct struct { id string } func (m *MyStruct) Id() { // doing something with id here } //then func foo(str *MyStruct2) { str.m.Id() } 

Si cambia MyStruct.Id a MyStruct.id , ya no podrá acceder a él para inicializar MyStruct2 , ya que solo se podrá acceder a la id a través de su propio paquete ( que es el first paquete ).

Esto se debe a que MyStruct y MyStruct2 están en paquetes diferentes.


Para resolver eso puedes hacer esto:

Paquete 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, } } 

Paquete 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"), }) }