Zainicjuj zagnieżdżoną strukturę

124

Nie mogę dowiedzieć się, jak zainicjować zagnieżdżoną strukturę. Znajdź przykład tutaj: 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
źródło
1
Właśnie uczyłem się iść i miałem dokładnie to samo pytanie. Możesz pominąć typy elementów dla tablic i map, ale nie dla zagnieżdżonych struktur. Nielogiczne i niewygodne. Czy ktoś może wyjaśnić, dlaczego?
Peter Dotchev,

Odpowiedzi:

177

Cóż, czy jest jakiś konkretny powód, aby nie tworzyć własnej struktury Proxy?

W każdym razie masz 2 opcje:

We właściwy sposób wystarczy przenieść proxy do jego własnej struktury, na przykład:

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

Mniej poprawny i brzydki sposób, ale nadal działa:

c := &Configuration{
    Val: "test",
    Proxy: struct {
        Address string
        Port    string
    }{
        Address: "addr",
        Port:    "80",
    },
}
OneOfOne
źródło
1
Czy w drugiej metodzie możemy uniknąć powtarzającej się definicji struktury?
Gaurav Ojha
@GauravOjha nie do końca, ale coś w rodzaju play.golang.org/p/n24BD3NlIR
OneOfOne
Myślę, że użycie typu osadzonego jest bardziej odpowiednie dla relacji is-a.
crackerplace
jak wskazano poniżej przez @sepehr, możesz uzyskać dostęp do zmiennych bezpośrednio za pomocą notacji kropkowej.
snassr
Co się stanie, jeśli proxy ma pole ze strukturą jako typ? Jak zainicjować je w innej zagnieżdżonej strukturze?
kucinghitam
90

Jeśli nie chcesz używać oddzielnej definicji struktury dla struktury zagnieżdżonej i nie lubisz drugiej metody sugerowanej przez @OneOfOne, możesz użyć tej trzeciej metody:

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

Możesz to sprawdzić tutaj: https://play.golang.org/p/WoSYCxzCF2

sepehr
źródło
8
Wow, prawdziwa odpowiedź na pytanie, jak zainicjować zagnieżdżone struktury.
Max
1
To jest całkiem niezłe, ale byłoby lepiej, gdybyśmy mogli to zrobić w jednej linii!
Gaurav Ojha
1
Szukałem sposobu, w którym nie musisz tego robić. c.Proxy.Address = `127.0.0.1` c.Proxy.Port = `8080` Czy istnieje sposób na zainicjowanie tych wartości podczas &Configuration{}przypisywania?
Matheus Felipe
1
@MatheusFelipe można ale wtedy trzeba określić Proxyjako własnej struktury, zobaczyć pierwszy sposób odpowiedź przez @OneOfOne
sepehr
IMO, to jest lepsze niż akceptowana odpowiedź.
domoarigato
14

Zdefiniuj swoją Proxystrukturę osobno, na zewnątrz Configuration, na przykład:

type Proxy struct {
    Address string
    Port    string
}

type Configuration struct {
    Val string
    P   Proxy
}

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

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

Vitor De Mario
źródło
A jeśli P Proxyjest tablicą?
Ertuğrul Altınboğa
10

Masz również tę opcję:

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
źródło
Tak lub to samo z drugim typem pola
Pierrick HYMBERT
A jeśli Proxyjest tablicą?
Ertuğrul Altınboğa
9

Jedna trudność pojawia się, gdy chcesz utworzyć wystąpienie typu publicznego zdefiniowanego w pakiecie zewnętrznym, a ten typ osadza inne typy, które są prywatne.

Przykład:

package animals

type otherProps{
  Name string
  Width int
}

type Duck{
  Weight int
  otherProps
}

Jak utworzyć instancję Duckwe własnym programie? Oto najlepsze, co mogłem wymyślić:

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
źródło
Dla tych, którzy zapomnieli jak ja, nazwij swoje atrybuty struktury dużymi literami, inaczej napotkasz cannot refer to unexported field or method błąd.
tagaizm
5

Możesz również przydzielić newi zainicjować wszystkie pola ręcznie

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

Zobacz na placu zabaw: https://play.golang.org/p/sFH_-HawO_M

Ferdy Pruis
źródło
2

Możesz zdefiniować strukturę i utworzyć jej obiekt w innej strukturze, tak jak zrobiłem to poniżej:

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

Mam nadzieję, że ci to pomogło :)

Vipin Gupta
źródło
2

Musisz ponownie zdefiniować nienazwaną strukturę podczas &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
źródło