以下问题有多种答案/技巧:

如何将默认值设置为golang结构? 如何初始化结构在golang

我有几个答案,但还需要进一步讨论。


当前回答

有一种使用标签的方法 允许多个默认值。

假设您有以下结构,默认有2个 标记default0和default1。

type A struct {
   I int    `default0:"3" default1:"42"`
   S string `default0:"Some String..." default1:"Some Other String..."`
}

现在可以设置默认值了。

func main() {

ptr := &A{}

Set(ptr, "default0")
fmt.Printf("ptr.I=%d ptr.S=%s\n", ptr.I, ptr.S)
// ptr.I=3 ptr.S=Some String...

Set(ptr, "default1")
fmt.Printf("ptr.I=%d ptr.S=%s\n", ptr.I, ptr.S)
// ptr.I=42 ptr.S=Some Other String...
}

这是一个操场上的完整程序。

如果你对一个更复杂的例子感兴趣,可以说with 切片和映射,然后,看看creasty/defaultse

其他回答

选项1的一个问题是 Victor Zamanian认为,如果没有导出类型,那么包的用户就不能将其声明为函数参数的类型等。解决这个问题的一种方法是导出一个接口,而不是输出结构。

package candidate
// Exporting interface instead of struct
type Candidate interface {}
// Struct is not exported
type candidate struct {
    Name string
    Votes uint32 // Defaults to 0
}
// We are forced to call the constructor to get an instance of candidate
func New(name string) Candidate {
    return candidate{name, 0}  // enforce the default value here
}

这允许我们使用导出的Candidate接口声明函数参数类型。 我从这个解决方案中看到的唯一缺点是,我们所有的方法都需要在接口定义中声明,但你可能会说这是一种很好的实践。

对于Go结构体中的默认值,我们使用匿名结构:

Person := struct {
    name      string
    age       int
    city      string
}{
    name:      "Peter",
    age:        21,
    city:      "Noida",
}

fmt.Println(人)

有一种使用标签的方法 允许多个默认值。

假设您有以下结构,默认有2个 标记default0和default1。

type A struct {
   I int    `default0:"3" default1:"42"`
   S string `default0:"Some String..." default1:"Some Other String..."`
}

现在可以设置默认值了。

func main() {

ptr := &A{}

Set(ptr, "default0")
fmt.Printf("ptr.I=%d ptr.S=%s\n", ptr.I, ptr.S)
// ptr.I=3 ptr.S=Some String...

Set(ptr, "default1")
fmt.Printf("ptr.I=%d ptr.S=%s\n", ptr.I, ptr.S)
// ptr.I=42 ptr.S=Some Other String...
}

这是一个操场上的完整程序。

如果你对一个更复杂的例子感兴趣,可以说with 切片和映射,然后,看看creasty/defaultse

做这样的东西怎么样:

// Card is the structure we work with
type Card struct {
    Html        js.Value
    DefaultText string `default:"html"` // this only works with strings
}

// Init is the main function that initiate the structure, and return it
func (c Card) Init() Card {
    c.Html = Document.Call("createElement", "div")
    return c
}

然后将其命名为:

c := new(Card).Init()

我发现这个帖子很有帮助,也很有教育意义。其他答案已经提供了很好的指导,但我想用一个易于参考的方法总结我的结论(即复制粘贴):

package main

import (
    "fmt"
)

// Define an interface that is exported by your package.
type Foo interface {
  GetValue() string // A function that'll return the value initialized with a default.
  SetValue(v string) // A function that can update the default value.
}

// Define a struct type that is not exported by your package.
type foo struct {
  value string
}

// A factory method to initialize an instance of `foo`,
// the unexported struct, with a default value.
func NewFoo() Foo {
  return &foo{
    value: "I am the DEFAULT value.",
  }
}

// Implementation of the interface's `GetValue`
// for struct `foo`.
func (f *foo) GetValue() string {
  return f.value
}

// Implementation of the interface's `SetValue`
// for struct `foo`.
func (f *foo) SetValue(v string) {
  f.value = v
}

func main() {
  f := NewFoo()
  fmt.Printf("value: `%s`\n", f.GetValue())
  f.SetValue("I am the UPDATED value.")
  fmt.Printf("value: `%s`\n", f.GetValue())
}