ネストされた構造体を初期化します


123

ネストされた構造体を初期化する方法がわかりません。ここで例を見つけてください: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
学ぶだけで、まったく同じ質問がありました。配列とマップの要素タイプは省略できますが、ネストされた構造体は省略できません。非論理的で不便。誰かが理由を説明できますか?
Peter Dotchev

回答:


176

さて、Proxyを独自の構造体にしない具体的な理由はありますか?

とにかく、2つのオプションがあります。

適切な方法は、単にプロキシを独自の構造体に移動することです。次に例を示します。

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

あまり適切ではなく醜い方法ですが、まだ機能します:

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

1
2番目の方法では、構造体の繰り返し定義を回避できますか?
Gaurav Ojha 2017年

@GauravOjhaがすべてではありませんが、play.golang.org
p / n24BD3NlIRの

埋め込み型を使用する方がis-aの関係に適していると思います。
クラッカーの場所2017

@sepehrで以下に指摘するように、ドット表記を使用して変数に直接アクセスできます。
snassr

プロキシに型として構造体のフィールドがある場合はどうなりますか?別のネストされた構造体内でそれらを初期化する方法は?
kucinghitam

89

ネストされた構造体の個別の構造体定義を使いたくなく、@ OneOfOneによって提案された2番目のメソッドが嫌いな場合は、この3番目のメソッドを使用できます。

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

ここで確認できます:https : //play.golang.org/p/WoSYCxzCF2


8
うわー、ネストされた構造体を初期化する方法の質問に対する実際の答え。
最大

1
これは実際にはかなり良いですが、1行で実行できればもっと良かったでしょう。
Gaurav Ojha 2017年

1
私はあなたがする必要がない方法を探していました 割り当てc.Proxy.Address = `127.0.0.1` c.Proxy.Port = `8080` 中にこれらの値を初期化する方法はあり&Configuration{}ますか?
Matheus Felipe

1
@MatheusFelipeはできますがProxy、独自の構造体として定義する必要があります。@ OneOfOneの回答の最初のメソッドを参照してください
sepehr

IMO、これは受け入れられた回答よりも優れています。
どもありがと



9

外部パッケージで定義されたパブリック型をインスタンス化し、その型がプライベートである他の型を埋め込む場合、1つの問題が発生します。

例:

package animals

type otherProps{
  Name string
  Width int
}

type Duck{
  Weight int
  otherProps
}

Duckを自分のプログラムでどのようにインスタンス化しますか?これが私が思いつくことができる最高のものです:

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

私のようにどのように忘れられたかについては、構造体の属性に大文字で名前を付けてくださいcannot refer to unexported field or method
タガリズム

5

newすべてのフィールドを手動で割り当てて初期化することもできます

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

遊び場で見る:https : //play.golang.org/p/sFH_-HawO_M


2

構造体を定義して、そのオブジェクトを別の構造体に作成することができます。

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

それがあなたを助けたことを願っています:)


2

中に名前のない構造体を再定義する必要があります &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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.