【问题标题】:How to initialize a nested struct?如何初始化嵌套结构?
【发布时间】:2020-10-09 16:05:59
【问题描述】:

我不知道如何初始化嵌套结构。在此处查找示例: 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",
        }
    }

}

【问题讨论】:

  • 刚学go,遇到了完全相同的问题。您可以省略数组和映射的元素类型,但不能省略嵌套结构。不合逻辑且不方便。有人能解释一下为什么吗?

标签: go


【解决方案1】:

嗯,有什么理由不让 Proxy 成为自己的结构吗?

无论如何你有两个选择:

正确的做法,简单的将proxy移到自己的struct中,例如:

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

【讨论】:

  • 第二种方法,能否避免重复的struct定义?
  • @GauravOjha 不是一路,而是像play.golang.org/p/n24BD3NlIR
  • 我认为使用嵌入式类型更适合 is-a 关系。
  • 正如@sepehr 指出的,您可以使用点符号直接访问变量。
  • 如果代理有一个结构为类型的字段怎么办?如何在另一个嵌套结构中初始化它们?
【解决方案2】:

如果您不想为嵌套结构使用单独的结构定义,并且您不喜欢@OneOfOne 建议的第二种方法,您可以使用第三种方法:

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

【讨论】:

  • 哇,如何初始化嵌套结构的问题的实际答案。
  • 这个其实挺好的,要是能一行就更好了!
  • 我一直在寻找一种不需要c.Proxy.Address = `127.0.0.1` c.Proxy.Port = `8080` 的方法,有没有办法在&Configuration{} 赋值期间初始化这些值?
  • @MatheusFelipe 你可以,但是你必须将Proxy 定义为它自己的结构,请参阅@OneOfOne 回答中的第一个方法
  • 当Proxy是一个数组时,Proxy []struct{}?
【解决方案3】:

Configuration 之外单独定义Proxy 结构,如下所示:

type Proxy struct {
    Address string
    Port    string
}

type Configuration struct {
    Val string
    P   Proxy
}

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

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

【讨论】:

  • 如果P Proxy 是一个数组呢?
【解决方案4】:

你也有这个选项:

type Configuration struct {
        Val string
        Proxy
}

type Proxy struct {
        Address string
        Port    string
}

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

【讨论】:

  • 是或与第二种初始化器相同field:value
  • 如果Proxy 是一个数组呢?
  • @ErtuğrulAltınboğa 在这种情况下,您可以使用append(pxyArr, Proxy{"addr", "port"})
【解决方案5】:

当您想要实例化在外部包中定义的公共类型并且该类型嵌入了其他私有类型时,就会出现一个问题。

例子:

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 错误。
【解决方案6】:

您也可以使用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

【讨论】:

  • 很好的例子+1。为清楚起见,您可以添加fmt.Println(c.Val, c.Proxy.Address, c.Proxy.Port)
【解决方案7】:

&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

【讨论】:

    【解决方案8】:

    您可以定义一个结构并在另一个结构中创建它的对象,如下所示:

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

    希望对你有所帮助:)

    【讨论】:

      【解决方案9】:
      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",
              },
          }
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多