go 结构体中的字段, 那种情况下定义为私有, 那种情况定义为公有?

2021-09-14 17:27:25 +08:00
 chaleaoch
因为私有字段也可以通过 字段+ get set 公有方法实现. -- Java 不都这么干吗?

但是我在翻 golang 开源项目中发现,似乎两种情况同时存在.

迷茫了...
1665 次点击
所在节点    Go 编程语言
12 条回复
01sw
2021-09-14 17:45:56 +08:00
好像是通过变量首字母大小写来决定访问权限
pkoukk
2021-09-14 17:50:34 +08:00
首先,get 和 set 不是必须成对出现啊,但是你暴露了字段出去,那一定允许外部读写。
其次,访问器里可以加逻辑的啊。

func (u *User) SetName(fullName string) {
u.fullName = fullName
u.familyName = strings.Split(fullName, " ")
}
func (u *User) Name() string {
return u.fullName
}
chaleaoch
2021-09-14 17:54:34 +08:00
@pkoukk 大佬我的意思是说:

在 Java bean 中 似乎 get set 是一种约定俗成的规范.
在 Go 中, 两种用法我都见过.

我的问题是:
哪种情况下, 推荐用哪种方式?
而不是为什么会有 get set?

谢谢大佬.
koolob
2021-09-14 18:00:23 +08:00
一般需要序列化的情况,字段要搞成公有。
另外如果就是单纯的读写,没有其他逻辑,搞成公有也没啥问题。显得更简洁一些。
LoNeFong
2021-09-14 18:15:41 +08:00
需要更改的就直接大写字段, 然后使用.去更改或者访问. 大型开源项目几乎都很少使用 getattr 和 setattr, 或者你看看 k8s 用了的是什么原因, 是为啥要加这个
pkoukk
2021-09-14 18:27:33 +08:00
@chaleaoch
没写过 java,但我理解应该是为了适配 java 那些框架所以才有的这些规范吧。
框架代码写的多了,很多人就把习惯推广到不用框架的地方了。

我在 go 里用 get set 多半是因为 interface,go 的 interface 只能包含方法。
chaleaoch
2021-09-14 18:35:12 +08:00
@pkoukk 我也没写过 java 不过 get set 似乎是现有的规范后有的框架,当然这些不重要.

get set 的其中一个优点是, 结构清晰, 如果项目变得很大, 有些字段不知道在哪里做的修改. 可以在 get set 里面下一个断点. 否则只能通过 全局搜索 挨个判断.

如果是 python 可以通过 property 解决. 如果是 Go 似乎没有什么好的办法, 也许我不知道.
chaleaoch
2021-09-14 18:37:27 +08:00
@LoNeFong 我没说 k8s 源码用的这个.

大型开源项目几乎都很少使用 getattr 和 setattr
哦哦 是没有明确定义这样的方法,. 但是有类似的 Get 或者之类.
譬如这种, 当然这个例子和我主贴中的描述有区别,但是 大致是一个意思.
```
func (s *Storage) Get(t settings.AuthMethod) (Auther, error) {
return s.back.Get(t)
}
```
cyrivlclth
2021-09-14 19:24:03 +08:00
如果是简单的 Set,就是一个等号,那不如就用公有的
如果是简单的 Get,就是一个 return,那不如就用公有的
如果是无所谓使用方能不能修改的,那不如就用公有的
你没发现 Java 里面的 get set 方法大多都是一句话吗?这种除了遵循规范,有什么实际意义呢?而 go 没有这种规范( kotlin 也没有这种规范,因为大家都觉得太啰嗦了)
当然也不是没有 get set 的情况,比如你的属性值需要计算得出,而不是简单的=,那就需要 get 和 set 方法了。但是私有之后的字段,序列化又成问题了,你又得写 Marshall 和 Unmarshall 方法。。。
tyx1703
2021-09-14 19:59:03 +08:00
我觉得如果需要检查值或者重构时应该用 get/set,没这个需求不如直接设置字段来的方便
Ansen
2021-09-14 20:09:24 +08:00
首字母大写为公有外部可调用,小写私有仅内部调用
Mitt
2021-09-15 00:38:28 +08:00
getter setter 的意义就是方便未来修改和重构以及增加触发器,否则直接公开字段更实用

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/801812

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX