İç 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.