LoginSignup
55
29

More than 5 years have passed since last update.

golangでnestしたstructの初期化がツライ

Last updated at Posted at 2015-10-11

以前作ったSlackに勉強会情報を飛ばすツールのテストを書いてて、nestしたstructをコード内で初期化するのがあまりにもツラかったのでメモを残します。
結局は避けたんですが、どうしてもやらなきゃいけない場合に参考になればということで。
あと、もっと良い方法がある気もするので、誰かから愛という名のマサカリが飛んでくることもちょっと期待しつつ。

ツライ

ということでツライです。

1nestしてるだけでツライ

まずこんなstructがあったとして、

nestしたstruct
type foo struct {
    bar struct {
        val1 int
        val2 int
    }
}

これをコード内で初期化するにはこうします。

初期化
var f = &foo{
    bar: struct {
        val1 int
        val2 int
    }{
        val1: 1,
        val2: 2,
    },
}

最後の

val1: 1,
val2: 2,

1,
2,

と省略して書くこともできます。
以下同様です。

nestのnestだともっとツライ

次に以下のようなnestのnestなstructがあったとします。

nestのnest
type foo struct {
    bar struct {
        boo struct {
            val1 int
            val2 int
        }
    }
}

これを初期化するにはこうします。

初期化
var f = &foo{
    bar: struct {
        boo struct {
            val1 int
            val2 int
        }
    }{
        boo: struct {
            val1 int
            val2 int
        }{
            val1: 1,
            val2: 2,
        },
    },
}

ツライ。

さらにnestが深くなるとこんなにツライ

さらにnestを深くした上で複雑にしてみます。

複雑なstruct
type foo struct {
    bar struct {
        val int
        boo []struct {
            far struct {
                val1 int
                val2 int
            }
        }
    }
}

これを初期化するにはこうします。

初期化
var f = &foo{
    bar: struct {
        val int
        boo []struct {
            far struct {
                val1 int
                val2 int
            }
        }
    }{
        val: 0,
        boo: []struct {
            far struct {
                val1 int
                val2 int
            }
        }{
            {
                far: struct {
                    val1 int
                    val2 int
                }{
                    val1: 1,
                    val2: 2,
                },
            },
        },
    },
}

つらたん(死語)ですね。

解決策1

nestしたstructを外だしのstructにすると割とすっきりします。
とりあえず最初のnestが一つのものを書くとこうなります。

structを外だし
type foo struct {
    bar
}

type bar struct {
    val1 int
    val2 int
}

初期化するときはこうなります。

初期化
var f = foo{
    bar: bar{
        val1: 1,
        val2: 2,
    },
}

だいぶ直感的に書けますね。

解決策が使えなくてツライ

でも例えば何らかの制約があって、複数のstructが同じ名前で構造が異なるstructをnestしなきゃいけないときとかは使えません。

解決策1が使えない
type foo struct {
    bar struct {
        val1 int
        val2 int
    }
}
type far struct {
    bar struct {
        val3 string
        val4 string
    }
}

foo内のbarとfar内のbarの型をそれぞれ別名のstructで割り当てられれば問題はないですが冗長な感は否めません。

解決策2

そもそもコードで初期化しないでファイルから読むなら普通にjsonで書けば良いので楽です。
が、ファイル増やすのもアレかもしれません。

ということで

結局使わなかったんですが、どうやるのか気になって時間をかけてしまったので、同じ道を辿った誰かの参考になれば幸いです。
まー、そんな変なstruct作んねーよ、とか、そんな変な制約ねーよ、とか、普通にファイルから読めば良いじゃん、みたいな感じですよねw
てゆーか、JSON書いてこれ使えばいいんじゃないか説がありますねw

でももっと良い解決策があったら、希望という名のマサカリでご指摘頂ければと思います。

55
29
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
55
29