Inicializar una estructura anidada


124

No puedo averiguar cómo inicializar una estructura anidada. Encuentre un ejemplo aquí: 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",
        },
    }

}

1
Acabo de aprender a ir y tenía exactamente la misma pregunta. Puede omitir tipos de elementos para matrices y mapas, pero no para estructuras anidadas. Ilógico e inconveniente. ¿Alguien puede explicar por qué?
— Peter Dotchev

Respuestas:


177

Bueno, ¿alguna razón específica para no hacer de Proxy su propia estructura?

De todos modos tienes 2 opciones:

La forma correcta, simplemente mueva el proxy a su propia estructura, por ejemplo:

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

La forma menos adecuada y fea, pero aún funciona:

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

1
En el segundo método, ¿podemos evitar la definición de estructura repetitiva?
— Gaurav Ojha

@GauravOjha no del todo, sino algo como play.golang.org/p/n24BD3NlIR
— OneOfOne

Creo que usar un tipo incrustado es más apto para una relación is-a.
— crackerplace

como se indica a continuación por @sepehr, puede acceder a las variables directamente utilizando la notación de puntos.
— snassr

¿Qué pasa si el proxy tiene un campo con estructura como tipo? ¿Cómo inicializarlos dentro de otra estructura anidada?
— kucinghitam

90

Si no desea ir con una definición de estructura separada para una estructura anidada y no le gusta el segundo método sugerido por @OneOfOne, puede usar este tercer 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`
}

Puedes consultarlo aquí: https://play.golang.org/p/WoSYCxzCF2


8
Vaya, una respuesta real a la pregunta de cómo inicializar estructuras anidadas .
— Máximo

1
Esto es realmente bastante bueno, ¡pero hubiera sido mejor si pudiéramos hacerlo en una línea!
— Gaurav Ojha

1
Estaba buscando una forma en la que no tendrías que hacerlo. c.Proxy.Address = `127.0.0.1` c.Proxy.Port = `8080` ¿Hay alguna forma de inicializar esos valores durante la &Configuration{}asignación?
— Matheus Felipe

1
@MatheusFelipe puede, pero luego debe definir Proxycomo su propia estructura, vea el primer método en la respuesta de @OneOfOne
— sepehr

En mi opinión, esto es mejor que la respuesta aceptada.
— domoarigato


10

También tienes esta opción:

type Configuration struct {
        Val string
        Proxy
}

type Proxy struct {
        Address string
        Port    string
}

func main() {
        c := &Configuration{"test", Proxy{"addr", "port"}}
        fmt.Println(c)
}

Sí o lo mismo con el segundo tipo de campo
— Pierrick HYMBERT

¿Y si Proxyes una matriz?
— Ertuğrul Altınboğa

9

Un problema surge cuando desea instanciar un tipo público definido en un paquete externo y ese tipo incrusta otros tipos que son privados.

Ejemplo:

package animals

type otherProps{
  Name string
  Width int
}

type Duck{
  Weight int
  otherProps
}

¿Cómo crea una instancia Ducken su propio programa? Aquí está lo mejor que se me ocurrió:

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"
}

Para aquellos que se han olvidado como yo, nombre sus atributos de estructura con letras mayúsculas; de lo contrario, se encontrará con un cannot refer to unexported field or method error.
— tagaism

5

También puede asignar newe inicializar todos los campos a mano

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"
}

Ver en el patio de recreo: https://play.golang.org/p/sFH_-HawO_M


2

Puede definir una estructura y crear su objeto en otra estructura como lo he hecho a continuación:

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 te haya ayudado :)


2

Necesita redefinir la estructura sin nombre 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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.