如何从字面上初始化GO中的多层嵌套结构?

时间:2019-01-10 09:51:15

标签: go struct composite-literals

我正在尝试在GO中从字面上初始化以下结构:

这是结构:

type tokenRequest struct {
    auth struct {
        identity struct {
            methods  []string
            password struct {
                user struct {
                    name   string
                    domain struct {
                        id string
                    }
                    password string
                }
            }
        }
    }
}

这是我的代码:

req := &tokenRequest{
    auth: struct {
        identity: struct {
            methods: []string{"password"},
            password: {
                user: {
                    name: os.Username,
                    domain: {
                        id: "default",
                    },
                    password: os.Password,
                },
            },
        },
    },
}

https://play.golang.org/p/e8Yuk-37_nN

是否可以在不单独定义所有嵌套结构的情况下进行初始化(即authidentitypassworduser

谢谢。

2 个答案:

答案 0 :(得分:4)

如果您有匿名的,未命名的结构类型,则只有重复结构定义,才能使用复合文字初始化它们。这很不方便。

因此,请改为使用命名的struct类型,这样您就可以在复合文字中使用它们,例如:

类型:

type domain struct {
    id string
}

type user struct {
    name     string
    domain   domain
    password string
}

type password struct {
    user user
}

type identity struct {
    methods  []string
    password password
}

type auth struct {
    identity identity
}

type tokenRequest struct {
    auth auth
}

然后将其初始化(在Go Playground上尝试):

req := &tokenRequest{
    auth: auth{
        identity: identity{
            methods: []string{"password"},
            password: password{
                user: user{
                    name: os.Username,
                    domain: domain{
                        id: "default",
                    },
                    password: os.Password,
                },
            },
        },
    },
}

查看相关问题:Unexpected return of anonymous struct

答案 1 :(得分:4)

可以,但是您将要输入批次

package main

import (
    "fmt"
    "net/http"
)

type tokenRequest struct {
    auth struct {
        identity struct {
            methods  []string
            password struct {
                user struct {
                    name   string
                    domain struct {
                        id string
                    }
                    password string
                }
            }
        }
    }
}

func main() {
    s := tokenRequest{
        auth: struct {
            identity struct {
                methods  []string
                password struct {
                    user struct {
                        name   string
                        domain struct {
                            id string
                        }
                        password string
                    }
                }
            }
        }{
            identity: struct {
                methods  []string
                password struct {
                    user struct {
                        name   string
                        domain struct {
                            id string
                        }
                        password string
                    }
                }
            }{
                methods: []string{http.MethodGet, http.MethodPost},
                password: struct {
                    user struct {
                        name   string
                        domain struct {
                            id string
                        }
                        password string
                    }
                }{
                    user: struct {
                        name   string
                        domain struct {
                            id string
                        }
                        password string
                    }{
                        name: "username",
                        domain: struct {
                            id string
                        }{
                            id: "domain id",
                        },
                        password: "password",
                    },
                },
            },
        },
    }

    fmt.Printf("%+v\n", s)
}

您必须告诉Go您要初始化什么类型的变量,因此您只需定义相同的匿名结构即可,但是每次都要确定但缓慢地删除一个级别。

因此,最好使用命名结构,这样您就不必重复自己了。