Initialiser une structure imbriquée

124

Je ne peux pas comprendre comment initialiser une structure imbriquée. Trouvez un exemple ici: 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
la source
1
Juste apprendre aller et avait exactement la même question. Vous pouvez omettre les types d'élément pour les tableaux et les mappes, mais pas pour les structures imbriquées. Illogique et peu pratique. Quelqu'un peut-il expliquer pourquoi?
Peter Dotchev

Réponses:

177

Eh bien, une raison spécifique pour ne pas faire de Proxy sa propre structure?

Quoi qu'il en soit, vous avez 2 options:

La bonne manière, déplacez simplement le proxy vers sa propre structure, par exemple:

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 manière la moins appropriée et la moins efficace mais qui fonctionne toujours

c := &Configuration{
    Val: "test",
    Proxy: struct {
        Address string
        Port    string
    }{
        Address: "addr",
        Port:    "80",
    },
}
OneOfOne
la source
1
Dans la deuxième méthode, pouvons-nous éviter la définition répétitive de struct?
Gaurav Ojha
@GauravOjha pas complètement, mais quelque chose comme play.golang.org/p/n24BD3NlIR
OneOfOne
Je pense que l'utilisation d'un type intégré est plus appropriée pour une relation is-a.
crackerplace
comme indiqué ci-dessous par @sepehr, vous pouvez accéder aux variables directement en utilisant la notation par points.
snassr
Que faire si le proxy a un champ avec struct comme type? Comment les initialiser dans une autre structure imbriquée?
kucinghitam
90

Si vous ne voulez pas utiliser une définition de structure distincte pour la structure imbriquée et que vous n'aimez pas la deuxième méthode suggérée par @OneOfOne, vous pouvez utiliser cette troisième méthode:

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

Vous pouvez le vérifier ici: https://play.golang.org/p/WoSYCxzCF2

sepehr
la source
8
Wow, une vraie réponse à la question de savoir comment initialiser les structures imbriquées .
Max
1
C'est en fait plutôt bien, mais cela aurait été mieux si nous pouvions le faire en une seule ligne!
Gaurav Ojha
1
Je cherchais une façon où vous ne devez faire c.Proxy.Address = `127.0.0.1` c.Proxy.Port = `8080` est - il un moyen d'initialiser ces valeurs lors de l' &Configuration{}affectation?
Matheus Felipe
1
@MatheusFelipe vous pouvez mais ensuite vous devez définir Proxycomme sa propre structure, voir la première méthode dans la réponse de @OneOfOne
sepehr
OMI, c'est mieux que la réponse acceptée.
domoarigato
14

Définissez votre Proxystructure séparément, en dehors de Configuration, comme ceci:

type Proxy struct {
    Address string
    Port    string
}

type Configuration struct {
    Val string
    P   Proxy
}

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

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

Vitor De Mario
la source
Et si P Proxyc'était un tableau?
Ertuğrul Altınboğa
10

Vous avez également cette option:

type Configuration struct {
        Val string
        Proxy
}

type Proxy struct {
        Address string
        Port    string
}

func main() {
        c := &Configuration{"test", Proxy{"addr", "port"}}
        fmt.Println(c)
}
José
la source
Oui ou la même chose avec le deuxième type de champ d'
Pierrick HYMBERT
Et si Proxyc'était un tableau?
Ertuğrul Altınboğa
9

Un problème survient lorsque vous souhaitez instancier un type public défini dans un package externe et que ce type intègre d'autres types qui sont privés.

Exemple:

package animals

type otherProps{
  Name string
  Width int
}

type Duck{
  Weight int
  otherProps
}

Comment instanciez-vous un Duckdans votre propre programme? Voici le meilleur que je pourrais trouver:

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
la source
Pour ceux qui ont oublié comme moi, nommez vos attributs struct avec des lettres majuscules, sinon vous ferez face à une cannot refer to unexported field or method erreur.
tagaism
5

Vous pouvez également allouer en utilisant newet initialiser tous les champs à la main

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

Voir dans le terrain de jeu: https://play.golang.org/p/sFH_-HawO_M

Ferdy Pruis
la source
2

Vous pouvez définir une structure et créer son objet dans une autre structure comme je l'ai fait ci-dessous:

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

J'espère que cela vous a aidé :)

Vipin Gupta
la source
2

Vous devez redéfinir la structure sans nom pendant &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
la source