İç içe geçmiş bir yapıyı başlatın


125

İç içe geçmiş bir yapıyı nasıl başlatacağımı çözemiyorum. Burada bir örnek bulun: 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
Sadece öğrenmeye devam et ve tam olarak aynı soruyu sordu. Diziler ve eşlemler için öğe türlerini atlayabilirsiniz, ancak iç içe yapılar için yapamazsınız. Mantıksız ve uygunsuz. Birisi nedenini açıklayabilir mi?
Peter Dotchev

Yanıtlar:


178

Peki, Proxy'yi kendi yapısı haline getirmemek için belirli bir neden var mı?

Neyse, 2 seçeneğiniz var:

Doğru yol, proxy'yi kendi yapısına taşıyın, örneğin:

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

Daha az uygun ve çirkin yol ama yine de işe yarıyor:

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

1
İkinci yöntemde, tekrar eden yapı tanımından kaçınabilir miyiz?
Gaurav Ojha

@GauravOjha tam olarak değil, play.golang.org/p/n24BD3NlIR
OneOfOne

Bence gömülü tip kullanmak, bir ilişki için daha uygun.
crackerplace

Aşağıda @sepehr tarafından belirtildiği gibi, değişkenlere doğrudan nokta notasyonunu kullanarak erişebilirsiniz.
snassr

Ya proxy, type olarak struct içeren bir alana sahipse? Bunları başka bir iç içe yapı içinde nasıl başlatabilirim?
kucinghitam

90

İç içe yapı için ayrı bir yapı tanımı yapmak istemiyorsanız ve @OneOfOne tarafından önerilen ikinci yöntemi sevmiyorsanız, bu üçüncü yöntemi kullanabilirsiniz:

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

Buradan kontrol edebilirsiniz: https://play.golang.org/p/WoSYCxzCF2


8
Vay canına, yuvalanmış yapıların nasıl başlatılacağı sorusuna gerçek bir yanıt .
Maksimum

1
Bu aslında oldukça iyi, ama tek satırda yapabilseydik daha iyi olurdu!
Gaurav Ojha

1
Yapmanız gerekmeyen bir yol arıyordum Atama c.Proxy.Address = `127.0.0.1` c.Proxy.Port = `8080` sırasında bu değerleri başlatmanın bir yolu var mı &Configuration{}?
Matheus Felipe

1
@MatheusFelipe yapabilirsiniz ama sonra Proxykendi yapısı olarak tanımlamalısınız , cevabın ilk metodu @OneOfOne
sepehr

IMO, bu kabul edilen cevaptan daha iyi.
domoarigato


10

Bu seçeneğe de sahipsiniz:

type Configuration struct {
        Val string
        Proxy
}

type Proxy struct {
        Address string
        Port    string
}

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

Evet veya ikinci tür başlatıcılarla aynı alan: değer
Pierrick HYMBERT

Ya Proxybir diziyse?
Ertuğrul Altınboğa

9

Bir sorun, harici bir pakette tanımlanmış bir genel türü başlatmak istediğinizde ve bu tür özel olan diğer türleri yerleştirdiğinde ortaya çıkar.

Misal:

package animals

type otherProps{
  Name string
  Width int
}

type Duck{
  Weight int
  otherProps
}

DuckKendi programınızda a'yı nasıl başlatırsınız ? İşte bulabildiğim en iyi şey:

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

Benim gibi unutanlar için struct özniteliklerinizi büyük harflerle adlandırın, aksi takdirde cannot refer to unexported field or method hata ile karşılaşırsınız.
tagaism

5

Ayrıca newtüm alanları el ile tahsis edebilir ve başlatabilirsiniz.

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

Oyun alanında görün: https://play.golang.org/p/sFH_-HawO_M


2

Aşağıda yaptığım gibi bir yapı tanımlayabilir ve nesnesini başka bir yapıda oluşturabilirsiniz:

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

Umarım size yardımcı olmuştur :)


2

Sırasında adsız yapıyı yeniden tanımlamanız gerekir &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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.