3

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

 2 years ago
source link: https://www.v2ex.com/t/801812
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

V2EX  ›  Go

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

  chaleaoch · 1 天前 · 742 次点击
因为私有字段也可以通过 字段+ get set 公有方法实现. -- Java 不都这么干吗?但是我在翻 golang 开源项目中发现,似乎两种情况同时存在.迷茫了...
12 条回复    2021-09-15 00:38:28 +08:00

01sw

01sw   1 天前

好像是通过变量首字母大小写来决定访问权限

pkoukk

pkoukk   1 天前

首先,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

chaleaoch   1 天前

@pkoukk 大佬我的意思是说:

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

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

谢谢大佬.

koolob

koolob   1 天前

一般需要序列化的情况,字段要搞成公有。
另外如果就是单纯的读写,没有其他逻辑,搞成公有也没啥问题。显得更简洁一些。

LoNeFong

LoNeFong   1 天前

需要更改的就直接大写字段, 然后使用.去更改或者访问. 大型开源项目几乎都很少使用 getattr 和 setattr, 或者你看看 k8s 用了的是什么原因, 是为啥要加这个

pkoukk

pkoukk   1 天前

@chaleaoch
没写过 java,但我理解应该是为了适配 java 那些框架所以才有的这些规范吧。
框架代码写的多了,很多人就把习惯推广到不用框架的地方了。

我在 go 里用 get set 多半是因为 interface,go 的 interface 只能包含方法。

chaleaoch

chaleaoch   1 天前

@pkoukk 我也没写过 java 不过 get set 似乎是现有的规范后有的框架,当然这些不重要.

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

如果是 python 可以通过 property 解决. 如果是 Go 似乎没有什么好的办法, 也许我不知道.

chaleaoch

chaleaoch   1 天前

@LoNeFong 我没说 k8s 源码用的这个.

大型开源项目几乎都很少使用 getattr 和 setattr
哦哦 是没有明确定义这样的方法,. 但是有类似的 Get 或者之类.
譬如这种, 当然这个例子和我主贴中的描述有区别,但是 大致是一个意思.
```
func (s *Storage) Get(t settings.AuthMethod) (Auther, error) {
return s.back.Get(t)
}
```

cyrivlclth

cyrivlclth   23 小时 44 分钟前   ❤️ 1

如果是简单的 Set,就是一个等号,那不如就用公有的
如果是简单的 Get,就是一个 return,那不如就用公有的
如果是无所谓使用方能不能修改的,那不如就用公有的
你没发现 Java 里面的 get set 方法大多都是一句话吗?这种除了遵循规范,有什么实际意义呢?而 go 没有这种规范( kotlin 也没有这种规范,因为大家都觉得太啰嗦了)
当然也不是没有 get set 的情况,比如你的属性值需要计算得出,而不是简单的=,那就需要 get 和 set 方法了。但是私有之后的字段,序列化又成问题了,你又得写 Marshall 和 Unmarshall 方法。。。

tyx1703

tyx1703   23 小时 9 分钟前   ❤️ 1

我觉得如果需要检查值或者重构时应该用 get/set,没这个需求不如直接设置字段来的方便

Ansen

Ansen   22 小时 59 分钟前

首字母大写为公有外部可调用,小写私有仅内部调用

Mitt

Mitt   18 小时 30 分钟前 via iPhone

getter setter 的意义就是方便未来修改和重构以及增加触发器,否则直接公开字段更实用

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK