次のようなgolang構造があります。
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
この関数を正しく呼び出すにはどうすればよいですか?
ありがとうございました
から http://golang.org/ref/spec#Exported_identifiers :
別のパッケージからのアクセスを許可するために、識別子をエクスポートできます。両方の場合、識別子がエクスポートされます:
- 識別子の名前の最初の文字はUnicodeの大文字(Unicodeクラス「Lu」)です。そして
- 識別子はパッケージブロックで宣言されているか、フィールド名またはメソッド名です。
したがって、基本的には大文字で始まる関数/変数のみがパッケージ外で使用できます。
例:
type MyStruct struct {
id string
}
func (m *MyStruct) Id() {
// doing something with id here
}
//then
func foo(str *MyStruct2) {
str.m.Id()
}
MyStruct.Id
をMyStruct.id
に変更すると、MyStruct2
を初期化するためにアクセスできなくなります。これは、id
が独自のパッケージ(これはfirst
package)です。
これは、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"),
})
}