web-dev-qa-db-ja.com

golang struct関数を呼び出すと、「エクスポートされていないフィールドまたはメソッドを参照できません」

次のような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

この関数を正しく呼び出すにはどうすればよいですか?

ありがとうございました

37
0xAX

から http://golang.org/ref/spec#Exported_identifiers

別のパッケージからのアクセスを許可するために、識別子をエクスポートできます。両方の場合、識別子がエクスポートされます:

  1. 識別子の名前の最初の文字はUnicodeの大文字(Unicodeクラス「Lu」)です。そして
  2. 識別子はパッケージブロックで宣言されているか、フィールド名またはメソッド名です。

したがって、基本的には大文字で始まる関数/変数のみがパッケージ外で使用できます。

例:

type MyStruct struct {
    id    string
}

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

//then

func foo(str *MyStruct2) {
    str.m.Id()
}
87
OneOfOne

MyStruct.IdMyStruct.idに変更すると、MyStruct2を初期化するためにアクセスできなくなります。これは、idが独自のパッケージ(これはfirst package)です。

これは、MyStructMyStruct2が異なるパッケージにあるためです。


これを解決するためにこれを行うことができます:

パッケージ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"),
    })
}
5
Inanc Gumus