J'ai une structure de golang quelque chose comme ceci:
type MyStruct struct {
Id string
}
et fonction:
func (m *MyStruct) id() {
// doing something with id here
}
J'ai aussi une autre structure comme celle-ci:
type MyStruct2 struct {
m *MyStruct
}
Maintenant, j'ai une fonction:
func foo(str *MyStruct2) {
str.m.id()
}
Mais je reçois une erreur au moment de la compilation:
str.m.id undefined (cannot refer to unexported field or method mypackage.(*MyStruct)."".id
Comment puis-je appeler correctement cette fonction?
Merci
De http://golang.org/ref/spec#Exported_identifiers :
Un identifiant peut être exporté pour permettre d'y accéder depuis un autre package. Un identifiant est exporté si les deux:
- le premier caractère du nom de l'identifiant est une lettre majuscule Unicode (classe Unicode "Lu"); et
- l'identifiant est déclaré dans le bloc de package ou il s'agit d'un nom de champ ou d'un nom de méthode.
Donc, fondamentalement, seules les fonctions/variables commençant par une majuscule seraient utilisables en dehors du package.
Exemple:
type MyStruct struct {
id string
}
func (m *MyStruct) Id() {
// doing something with id here
}
//then
func foo(str *MyStruct2) {
str.m.Id()
}
Si vous changez MyStruct.Id
à MyStruct.id
, vous ne pourrez plus y accéder pour initialiser MyStruct2
, car, id
sera accessible uniquement via son propre package ( qui est first
package ).
En effet, MyStruct
et MyStruct2
sont dans des packages différents.
Pour résoudre ce problème, vous pouvez le faire:
Paquet 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,
}
}
Paquet 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"),
})
}