Как буквально инициализировать многоуровневые вложенные структуры в GO?

Я пытаюсь буквально инициализировать следующую структуру в 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

Можно ли инициализировать без определения всех вложенных структур по отдельности (т.е. auth, identity, password, user)

Спасибо.

2 ответа

Решение

Вы можете, но вы будете много печатать:

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, какой тип переменной вы инициализируете, так что вы просто определяете одну и ту же анонимную структуру, медленно, но верно удаляя уровень каждый раз.

По этой причине лучше использовать именованные структуры, чтобы вам не пришлось повторяться.

Если у вас есть анонимные, безымянные структурные типы, вы можете инициализировать их только составными литералами, если вы повторите определение структуры. Это очень неудобно.

Поэтому вместо этого используйте именованные типы структур, чтобы вы могли использовать их в составных литералах следующим образом:

Типы:

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):

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

Смотрите связанный вопрос: Неожиданный возврат анонимной структуры

Другие вопросы по тегам