Mazn.net

やってみて 調べてみて 苦労しなけりゃ 箱は動かじ

Go言語の構造体をネスト

      2019/02/05

最近GO言語を勉強していて、ネスト(入れ子)された構造体のフィールドにアクセスする際のことをメモしておきます。

以下のように、中にmydata1をもつ構造体maindataを作ってみます。

package main

import "fmt"

type mydata1 struct {
    a int
    b int
    c int
}

type maindata struct {
    m1 mydata1
    e  int
}

func main() {
    d1 := mydata1{a: 11, b: 12, c: 13}
    mdata := maindata{m1: d1, e: 99}
    fmt.Println(mdata)
    fmt.Println(mdata.m1.a)
    fmt.Println(mdata.m1.b)
    fmt.Println(mdata.m1.c)
    fmt.Println(mdata.e)
}

上記のように、mydata1は、m1というフィールド名で定義されているので、mydata1のa~cにアクセスするには、mdata.m1.X と書く必要があります。上記を実行すると以下のようになります。想定通りですよね。

{{11 12 13} 99}
11
12
13
99

 

maindata構造体を定義するときに、フィールド名を省略することができるようです。省略すると、以下のようにmaindataのフィールド名を省略し直接mydata1のフィールド名にアクセスできるようです。なお、構造体を初期化する時、フィールド名が無いので型名(mydata1)を使うようです。

package main

import "fmt"

type mydata1 struct {
    a int
    b int
    c int
}

type maindata struct {
    mydata1
    e int
}

func main() {
    d1 := mydata1{a: 11, b: 12, c: 13}
    mdata := maindata{mydata1: d1, e: 99}
    fmt.Println(mdata)
    fmt.Println(mdata.a)
    fmt.Println(mdata.b)
    fmt.Println(mdata.c)
    fmt.Println(mdata.e)
}

これを実行すると以下のようになります。

{{11 12 13} 99}
11
12
13
99

では、以下のように、maindataに、mydata1と同じフィールド名があるとどうなるのでしょうか?

package main

import "fmt"

type mydata1 struct {
    a int
    b int
    c int
}

type maindata struct {
    mydata1
    a int
}

func main() {
    d1 := mydata1{a: 11, b: 12, c: 13}
    mdata := maindata{mydata1: d1, a: 99}
    fmt.Println(mdata)
    fmt.Println(mdata.a)
}

これを実行すると、以下のように、親(ネスト元)のフィールドaの値が優先されるようです。

{{11 12 13} 99}
99

では、ネストする構造体が2つ以上あり、その構造体に同じフィールド名があるとどうなるのでしょうか?やってみます。

import "fmt"

type mydata1 struct {
    a int
    b int
    c int
}

type mydata2 struct {
    a int
    b int
    c int
}

type maindata struct {
    mydata1
    mydata2
    a int
}

func main() {
    d1 := mydata1{a: 11, b: 12, c: 13}
    d2 := mydata2{a: 21, b: 22, c: 23}
    mdata := maindata{mydata1: d1, mydata2: d2, a: 99}
    fmt.Println(mdata)
    fmt.Println(mdata.b)
}

これを実行すると、以下のようにmydata1にもmydata2にもbというフィールドがあって曖昧なため、コンパイル時にエラーになりました。

./main.go:28:19: ambiguous selector mdata.b

なお、上記はmdata.bにアクセスしていますが、mdata.aの場合、親にaというフィールドがあるため、コンパイルエラーにならず、99が表示されます。

以上、GO言語の実験でした。

環境 : GOバージョン 1.11.4 on Linux

 - IT技術, プログラミング

336px

Message

メールアドレスが公開されることはありません。

  関連記事

no image
iptables のルールの移行

移行元のルールを保存し、 # iptables-save > filena …

no image
iptablesの設定を保存し起動時に自動的に反映する@Ubuntu 12.04 server

Ubuntu の iptables の設定を保存するには、iptables-pe …

no image
Windows XPのディスクアクセスがうるさいので自動デフラグを無効にする

今更ですが、Windows XP を使っていると、ディスクがカリカリとうるさいな …

k3dを使ってマルチノード構成のKubernetesを一瞬で構築する

一昔前までは、Kubernetesの学習環境を手元に作るには、それなりに手間がか …

no image
WordPress高負荷対策→同一ApacheのIPのアクセス数制限@CentOS 5

一日に数回サーバ高負荷で応答がなくなってしまって困っていました。load ave …

no image
Trackpointでスクロールできない@ThinkPad キーボード 55Y9024 with Windows7 64bit

ThinkPadのトラックポイントキーボード 55Y9024 を使っているのです …

no image
Flashのインストール@Fedora 17

LinuxにFlashインストールするのも随分楽になりました。 今ではAdobe …

no image
rubyの文字コードについて考える

rubyでは、1.6以降漢字コードを特別に解釈しなくなったようです。 maznは …

no image
Androidのアプリ内課金の支払いアカウントを変更する

Androidのスマホに複数のGoogleアカウントを登録し、アプリをインストー …

no image
py2exeでpythonをWindowsの実行ファイル形式にする@Windows 7 64bit

python でちょこっと作プログラムを誰かに渡したいとき、相手にpython入 …