Inicialize uma estrutura aninhada

124

Não consigo descobrir como inicializar uma estrutura aninhada. Encontre um exemplo aqui: http://play.golang.org/p/NL6VXdHrjh

package main

type Configuration struct {
    Val   string
    Proxy struct {
        Address string
        Port    string
    }
}

func main() {

    c := &Configuration{
        Val: "test",
        Proxy: {
            Address: "addr",
            Port:    "80",
        },
    }

}
sontags
fonte
1
Acabei de aprender e tive exatamente a mesma dúvida. Você pode omitir tipos de elementos para matrizes e mapas, mas não para estruturas aninhadas. Ilógico e inconveniente. Alguém pode explicar por quê?
Peter Dotchev

Respostas:

177

Bem, há alguma razão específica para não tornar o Proxy sua própria estrutura?

De qualquer forma, você tem 2 opções:

Da maneira correta, basta mover o proxy para sua própria estrutura, por exemplo:

type Configuration struct {
    Val string
    Proxy Proxy
}

type Proxy struct {
    Address string
    Port    string
}

func main() {

    c := &Configuration{
        Val: "test",
        Proxy: Proxy{
            Address: "addr",
            Port:    "port",
        },
    }
    fmt.Println(c)
    fmt.Println(c.Proxy.Address)
}

A maneira menos adequada e feia, mas ainda funciona:

c := &Configuration{
    Val: "test",
    Proxy: struct {
        Address string
        Port    string
    }{
        Address: "addr",
        Port:    "80",
    },
}
OneOfOne
fonte
1
No segundo método, podemos evitar a definição repetitiva de estrutura?
Gaurav Ojha
@GauravOjha não totalmente, mas algo como play.golang.org/p/n24BD3NlIR
OneOfOne
Acho que usar um tipo incorporado é mais adequado para o relacionamento é-um.
crackerplace de
conforme indicado abaixo por @sepehr, você pode acessar as variáveis ​​diretamente usando a notação de ponto.
snassr
E se o proxy tiver um campo com tipo struct? Como inicializá-los dentro de outra estrutura aninhada?
kucinghitam
90

Se você não quiser usar uma definição de struct separada para struct aninhada e não gostar do segundo método sugerido por @OneOfOne, você pode usar este terceiro método:

package main
import "fmt"
type Configuration struct {
    Val   string
    Proxy struct {
        Address string
        Port    string
    }
}

func main() {
    c := &Configuration{
        Val: "test",
    }

    c.Proxy.Address = `127.0.0.1`
    c.Proxy.Port = `8080`
}

Você pode verificar aqui: https://play.golang.org/p/WoSYCxzCF2

sepehr
fonte
8
Uau, uma resposta real para a questão de como inicializar estruturas aninhadas .
Máx.
1
Isso é realmente muito bom, mas teria sido melhor se pudéssemos fazer em uma linha!
Gaurav Ojha
1
Eu estava procurando uma maneira em que você não precisasse. c.Proxy.Address = `127.0.0.1` c.Proxy.Port = `8080` Existe uma maneira de inicializar esses valores durante a &Configuration{}atribuição?
Matheus Felipe
1
@MatheusFelipe você pode, mas então você tem que definir Proxycomo sua própria estrutura, veja o primeiro método na resposta de @OneOfOne
setembro
IMO, isso é melhor do que a resposta aceita.
domoarigato
14

Defina sua Proxyestrutura separadamente, fora de Configuration, assim:

type Proxy struct {
    Address string
    Port    string
}

type Configuration struct {
    Val string
    P   Proxy
}

c := &Configuration{
    Val: "test",
    P: Proxy{
        Address: "addr",
        Port:    "80",
    },
}

Consulte http://play.golang.org/p/7PELCVsQIc

Vitor de mario
fonte
E se P Proxyfor uma matriz?
Ertuğrul Altınboğa
10

Você também tem esta opção:

type Configuration struct {
        Val string
        Proxy
}

type Proxy struct {
        Address string
        Port    string
}

func main() {
        c := &Configuration{"test", Proxy{"addr", "port"}}
        fmt.Println(c)
}
Jose
fonte
Sim ou o mesmo com o segundo tipo de campo
Pierrick HYMBERT
E se Proxyfor uma matriz?
Ertuğrul Altınboğa
9

Uma pegadinha surge quando você deseja instanciar um tipo público definido em um pacote externo e esse tipo incorpora outros tipos que são privados.

Exemplo:

package animals

type otherProps{
  Name string
  Width int
}

type Duck{
  Weight int
  otherProps
}

Como você instancia um Duckem seu próprio programa? Aqui está o melhor que pude pensar:

package main

import "github.com/someone/animals"

func main(){
  var duck animals.Duck
  // Can't instantiate a duck with something.Duck{Weight: 2, Name: "Henry"} because `Name` is part of the private type `otherProps`
  duck.Weight = 2
  duck.Width = 30
  duck.Name = "Henry"
}
dvdplm
fonte
Para aqueles que se esqueceram como eu, nomeie seus atributos de estrutura com letras maiúsculas, caso contrário, você enfrentará o cannot refer to unexported field or method erro.
tagaism
5

Você também pode alocar usando newe inicializar todos os campos manualmente

package main

type Configuration struct {
    Val   string
    Proxy struct {
        Address string
        Port    string
    }
}

func main() {
    c := new(Configuration)
    c.Val = "test"
    c.Proxy.Address = "addr"
    c.Proxy.Port = "80"
}

Veja no playground: https://play.golang.org/p/sFH_-HawO_M

Ferdy Pruis
fonte
2

Você pode definir uma estrutura e criar seu objeto em outra estrutura, como fiz abaixo:

package main

import "fmt"

type Address struct {
    streetNumber int
    streetName   string
    zipCode      int
}

type Person struct {
    name    string
    age     int
    address Address
}

func main() {
    var p Person
    p.name = "Vipin"
    p.age = 30
    p.address = Address{
        streetName:   "Krishna Pura",
        streetNumber: 14,
        zipCode:      475110,
    }
    fmt.Println("Name: ", p.name)
    fmt.Println("Age: ", p.age)
    fmt.Println("StreetName: ", p.address.streetName)
    fmt.Println("StreeNumber: ", p.address.streetNumber)
}

Espero que tenha ajudado :)

Vipin Gupta
fonte
2

Você precisa redefinir a estrutura sem nome durante &Configuration{}

package main

import "fmt"

type Configuration struct {
    Val   string
    Proxy struct {
        Address string
        Port    string
    }
}

func main() {

    c := &Configuration{
        Val: "test",
        Proxy: struct {
            Address string
            Port    string
        }{
            Address: "127.0.0.1",
            Port:    "8080",
        },
    }
    fmt.Println(c)
}

https://play.golang.org/p/Fv5QYylFGAY

Lizhenpeng
fonte