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.