Inisialisasi struct bertingkat

124

Saya tidak tahu cara menginisialisasi struct bersarang. Temukan contohnya di sini: 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
sumber
1
Baru belajar pergi dan punya pertanyaan yang persis sama. Anda bisa menghilangkan tipe elemen untuk array dan peta tapi tidak untuk struct bertingkat. Tidak logis dan tidak nyaman. Bisakah seseorang menjelaskan mengapa?
Peter Dotchev

Jawaban:

177

Nah, ada alasan khusus untuk tidak menjadikan Proxy struct sendiri?

Bagaimanapun Anda memiliki 2 opsi:

Cara yang tepat, cukup pindahkan proxy ke struct miliknya sendiri, misalnya:

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

Cara yang kurang tepat dan jelek tapi masih berhasil:

c := &Configuration{
    Val: "test",
    Proxy: struct {
        Address string
        Port    string
    }{
        Address: "addr",
        Port:    "80",
    },
}
OneOfOne
sumber
1
Dalam metode kedua, dapatkah kita menghindari definisi struct berulang?
Gaurav Ojha
@GauravOjha tidak sepenuhnya, tapi sesuatu seperti play.golang.org/p/n24BD3NlIR
OneOfOne
Saya pikir menggunakan tipe tertanam lebih cocok untuk hubungan is-a.
crackerplace
seperti yang ditunjukkan oleh @sepehr di bawah ini, Anda dapat mengakses variabel secara langsung menggunakan notasi titik.
snassr
Bagaimana jika proxy memiliki field dengan tipe struct sebagai? Bagaimana cara menginisialisasi mereka di dalam struct bersarang lain?
kucinghitam
90

Jika Anda tidak ingin menggunakan definisi struct terpisah untuk struct bersarang dan Anda tidak menyukai metode kedua yang disarankan oleh @OneOfOne, Anda dapat menggunakan metode ketiga ini:

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

Anda dapat memeriksanya di sini: https://play.golang.org/p/WoSYCxzCF2

sepehr
sumber
8
Wow, jawaban sebenarnya untuk pertanyaan tentang cara menginisialisasi struct bersarang .
Maksimal
1
Ini sebenarnya cukup bagus, tetapi akan lebih baik jika kita bisa melakukannya dalam satu baris!
Gaurav Ojha
1
Saya sedang mencari cara di mana Anda tidak perlu melakukan c.Proxy.Address = `127.0.0.1` c.Proxy.Port = `8080` Apakah ada cara untuk menginisialisasi nilai-nilai tersebut selama &Configuration{}penugasan?
Matheus Felipe
1
@MatheusFelipe Anda bisa tetapi kemudian Anda harus mendefinisikan Proxysebagai struct sendiri, lihat metode pertama dalam jawaban oleh @OneOfOne
sepehr
IMO, ini lebih baik dari jawaban yang diterima.
domoarigato
14

Tentukan Proxystruct Anda secara terpisah, di luar Configuration, seperti ini:

type Proxy struct {
    Address string
    Port    string
}

type Configuration struct {
    Val string
    P   Proxy
}

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

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

Vitor De Mario
sumber
Bagaimana jika P Proxysebuah array?
Ertuğrul Altınboğa
10

Anda juga memiliki opsi ini:

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
sumber
Ya atau sama dengan bidang
Pierrick HYMBERT
Bagaimana jika Proxysebuah array?
Ertuğrul Altınboğa
9

Satu gotcha muncul ketika Anda ingin membuat instance tipe publik yang ditentukan dalam paket eksternal dan tipe itu menyematkan tipe lain yang privat.

Contoh:

package animals

type otherProps{
  Name string
  Width int
}

type Duck{
  Weight int
  otherProps
}

Bagaimana Anda membuat contoh Duckdi program Anda sendiri? Inilah yang terbaik yang bisa saya hasilkan:

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.dll
sumber
Bagi yang lupa seperti saya, beri nama atribut struct Anda dengan huruf kapital jika tidak, Anda akan menghadapi cannot refer to unexported field or method kesalahan.
tagaism
5

Anda juga dapat mengalokasikan menggunakan newdan menginisialisasi semua bidang dengan tangan

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

Lihat di taman bermain: https://play.golang.org/p/sFH_-HawO_M

Ferdy Pruis
sumber
2

Anda dapat menentukan struct dan membuat objeknya di struct lain seperti yang telah saya lakukan di bawah ini:

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

Semoga membantu Anda :)

Vipin Gupta
sumber
2

Anda perlu mendefinisikan ulang struct tak bernama selama &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
sumber