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

}

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

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


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


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

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

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


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é :)


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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.