如何在Golang结构中设置和获取字段?

nop*_*ope 54 struct get set go

创建这样的结构后:

type Foo struct {
   name string        

}
func (f Foo) SetName(name string){
    f.name=name
}

func (f Foo) GetName string (){
   return f.name
}
Run Code Online (Sandbox Code Playgroud)

如何创建Foo的新实例并设置并获取名称?我尝试了以下方法:

p:=new(Foo)
p.SetName("Abc")
name:=p.GetName()
fmt.Println(name)
Run Code Online (Sandbox Code Playgroud)

没有打印,因为名称是空的.那么如何设置并获取结构中的字段?

Mos*_*vah 112

评论(和工作)示例:

package main

import "fmt"

type Foo struct {
    name string
}

// SetName receives a pointer to Foo so it can modify it.
func (f *Foo) SetName(name string) {
    f.name = name
}

// Name receives a copy of Foo since it doesn't need to modify it.
func (f Foo) Name() string {
    return f.name
}

func main() {
    // Notice the Foo{}. The new(Foo) was just a syntactic sugar for &Foo{}
    // and we don't need a pointer to the Foo, so I replaced it.
    // Not relevant to the problem, though.
    p := Foo{}
    p.SetName("Abc")
    name := p.Name()
    fmt.Println(name)
}
Run Code Online (Sandbox Code Playgroud)

测试它并参加A Tour of Go以了解有关方法和指针的更多信息,以及Go的基础知识.

  • Name()将是getter的惯用名(请参阅http://golang.org/doc/effective_go.html#Getters) (15认同)
  • 吸气剂需要复印件的价格是多少?它实际上复制了整个结构吗? (2认同)

Vol*_*ker 24

getter和setter方法是不是那个地道为Go.特别是字段x的getter不是名为GetX而只是X.请参阅http://golang.org/doc/effective_go.html#Getters

如果setter没有提供特殊的逻辑,例如验证逻辑,那么导出字段并没有提供setter或getter方法都没有错.(对于拥有Java背景的人来说,这感觉不对.但事实并非如此.)

  • 信息隐藏(封装)的部分原因是程序演变.您只需通过直接访问即可在任何地方拼凑您的代码.让我们说,1年后,你决定实施验证或甚至有点不同的东西.你不想重构一千个不同的地方,只需要一个文件和一个地方.从其他语言中抛弃既定的实践和思想并不总是正确的做法. (16认同)
  • @sat(和所有的upvoters):在Go中重构数千个呼叫站点并不复杂.Gofix仍然存在,其他工具正在快速成熟.最后并非最不重要:仅仅因为您可能想要更改此访问权限而包含所有访问权限违反了YAGNI并且仅在您重构时才有帮助**可以通过单独更改getter来完成(没有额外的错误情况,没有其他重构).我经常听到这些争论.如果API设计得很好,你将不会遇到这些问题,如果API不好,你还是会丢失. (5认同)
  • @sat 如果你必须重构一千个地方,也许你一开始就做错了什么。 (2认同)

pet*_*rSO 5

例如,

package main

import "fmt"

type Foo struct {
    name string
}

func (f *Foo) SetName(name string) {
    f.name = name
}

func (f *Foo) Name() string {
    return f.name
}

func main() {
    p := new(Foo)
    p.SetName("Abc")
    name := p.Name()
    fmt.Println(name)
}
Run Code Online (Sandbox Code Playgroud)

输出:

Abc
Run Code Online (Sandbox Code Playgroud)

  • 虽然从技术上讲你的答案是可行的,但 GetFoo() 不是 Go 中 Foo 的惯用吸气剂命名:它应该只是 Foo()。Zipboxer 的回答中有更多细节。 (3认同)
  • 这是一个很好的例子,但是对于 `GetName()` 方法,你不需要通过指针 `func(f *Foo)` 传递它,你应该可以使用 `func(f Foo)`,因为你不需要修改您刚刚读取/返回的值。 (2认同)