sontags
sontags

Reputation: 3241

How to initialize a nested struct?

I cannot figure out how to initialize a nested struct. Find an example here: 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",
        }
    }

}

Upvotes: 217

Views: 257874

Answers (11)

Jonathan Richards
Jonathan Richards

Reputation: 1444

Here's another option I haven't seen mentioned:

package main

import (
    "encoding/json"
    "fmt"
    "log"
)

type Configuration struct {
    Val   string
    Proxy struct {
        Address string
        Port    string
    }
}

func main() {
    c := Configuration{}
    err := json.Unmarshal([]byte(fmt.Sprintf(`
    {
        "Val": "%s",
        "Proxy": {
            "Address": "%s",
            "Port": "%s"
        }
    }`, "test", "addr", "80")), &c)
    if err != nil {
        log.Fatalf("Error unmarshalling config: %v", err)
    }
}

I wouldn't recommend you actually do this, but I found it strange that this was possible and the syntax in the question wasn't. There is no technical limitation (except maybe compiler speed), but Golang hasn't implemented it, so we have to make do with one of the other answers. It may be for stylistic reasons, considering the existence of articles like Always abstract nested types in TypeScript.

Upvotes: 0

ceving
ceving

Reputation: 23754

When your configuration is something global, you can do it this way:

package main

var Configuration struct {
    Val   string
    Proxy struct {
        Address string
        Port    string
    }
}

func main() {
    Configuration.Val = "test"
    Configuration.Proxy.Address = "addr"
    Configuration.Proxy.Port = "80"
}

Upvotes: 2

jamlee
jamlee

Reputation: 1353

package main

type    Proxy struct {
        Address string
        Port    string
    }

type Configuration struct {
    Proxy
    Val   string

}

func main() {

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

}

Upvotes: 2

OneOfOne
OneOfOne

Reputation: 99195

Well, any specific reason to not make Proxy its own struct?

Anyway you have 2 options:

The proper way, simply move proxy to its own struct, for example:

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

The less proper and ugly way but still works:

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

Upvotes: 267

Ferdy
Ferdy

Reputation: 1201

You also could allocate using new and initialize all fields by hand

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

See in playground: https://play.golang.org/p/sFH_-HawO_M

Upvotes: 12

lizhenpeng
lizhenpeng

Reputation: 81

You need to redefine the unnamed struct during &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

Upvotes: 8

Vipin Gupta
Vipin Gupta

Reputation: 35

You can define a struct and create its object in another struct like i have done below:

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

Hope it helped you :)

Upvotes: 2

sepehr
sepehr

Reputation: 5729

If you don't want to go with separate struct definition for nested struct and you don't like second method suggested by @OneOfOne you can use this third method:

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

You can check it here: https://play.golang.org/p/WoSYCxzCF2

Upvotes: 186

dvdplm
dvdplm

Reputation: 691

One gotcha arises when you want to instantiate a public type defined in an external package and that type embeds other types that are private.

Example:

package animals

type otherProps{
  Name string
  Width int
}

type Duck{
  Weight int
  otherProps
}

How do you instantiate a Duck in your own program? Here's the best I could come up with:

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

Upvotes: 9

Jose
Jose

Reputation: 134

You have this option also:

type Configuration struct {
        Val string
        Proxy
}

type Proxy struct {
        Address string
        Port    string
}

func main() {
        c := &Configuration{"test", Proxy{"addr", "port"}}
        fmt.Println(c)
}

Upvotes: 13

Vitor De Mario
Vitor De Mario

Reputation: 1169

Define your Proxy struct separately, outside of Configuration, like this:

type Proxy struct {
    Address string
    Port    string
}

type Configuration struct {
    Val string
    P   Proxy
}

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

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

Upvotes: 18

Related Questions