Inizializza una struttura annidata


124

Non riesco a capire come inizializzare una struttura nidificata. Trova un esempio qui: 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
Sto solo imparando e ho avuto esattamente la stessa domanda. È possibile omettere i tipi di elemento per array e mappe ma non per strutture nidificate. Illogico e scomodo. Qualcuno può spiegare perché?
— Peter Dotchev

Risposte:


177

Ebbene, qualche ragione specifica per non rendere Proxy la propria struttura?

Comunque hai 2 opzioni:

Nel modo corretto, sposta semplicemente il proxy nella sua struttura, ad esempio:

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

Il modo meno corretto e brutto ma funziona ancora:

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

1
Nel secondo metodo, possiamo evitare la definizione di struttura ripetitiva?
— Gaurav Ojha

@GauravOjha non completamente, ma qualcosa come play.golang.org/p/n24BD3NlIR
— OneOfOne

Penso che l'uso di un tipo incorporato sia più adatto per una relazione.
— crackerplace

come indicato di seguito da @sepehr è possibile accedere alle variabili direttamente utilizzando la notazione punto.
— snassr

Cosa succede se il proxy ha un campo con struct come tipo? Come inizializzarli all'interno di un'altra struttura annidata?
— kucinghitam

90

Se non vuoi andare con la definizione di una struttura separata per la struttura nidificata e non ti piace il secondo metodo suggerito da @OneOfOne, puoi usare questo terzo metodo:

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

Puoi verificarlo qui: https://play.golang.org/p/WoSYCxzCF2


8
Wow, una risposta reale alla domanda su come inizializzare le strutture annidate .
— Max

1
In realtà è abbastanza buono, ma sarebbe stato meglio se avessimo potuto farlo in una riga!
— Gaurav Ojha

1
Stavo cercando un modo in cui non avresti bisogno di fare c.Proxy.Address = `127.0.0.1` c.Proxy.Port = `8080` C'è un modo per inizializzare quei valori durante l' &Configuration{}assegnazione?
— Matheus Felipe

1
@MatheusFelipe puoi ma poi devi definire Proxycome una propria struttura, vedi il primo metodo nella risposta di @OneOfOne
— sepehr

IMO, questo è meglio della risposta accettata.
— domoarigato


10

Hai anche questa opzione:

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 stesso con il secondo tipo di campo
— Pierrick HYMBERT

E se Proxyfosse un array?
— Ertuğrul Altınboğa,

9

Un problema si presenta quando si desidera creare un'istanza di un tipo pubblico definito in un pacchetto esterno e quel tipo incorpora altri tipi privati.

Esempio:

package animals

type otherProps{
  Name string
  Width int
}

type Duck{
  Weight int
  otherProps
}

Come si crea un'istanza di a Ducknel proprio programma? Ecco il meglio che sono riuscito a trovare:

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

Per coloro che si sono dimenticati come me, dai un nome agli attributi della struttura con lettere maiuscole, altrimenti dovrai affrontare un cannot refer to unexported field or method errore.
— tagaismo

5

Puoi anche allocare usando newe inizializzare tutti i campi 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"
}

Vedi nel playground: https://play.golang.org/p/sFH_-HawO_M


2

Puoi definire una struttura e creare il suo oggetto in un'altra struttura come ho fatto di seguito:

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

Spero ti abbia aiutato :)


2

È necessario ridefinire la struttura senza 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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.