V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
chaleaoch
V2EX  ›  Go 编程语言

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

  •  
  •   chaleaoch · 2021-09-14 17:27:25 +08:00 · 1664 次点击
    这是一个创建于 1164 天前的主题,其中的信息可能已经有所发展或是发生改变。
    因为私有字段也可以通过 字段+ get set 公有方法实现. -- Java 不都这么干吗?

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

    迷茫了...
    12 条回复    2021-09-15 00:38:28 +08:00
    01sw
        1
    01sw  
       2021-09-14 17:45:56 +08:00
    好像是通过变量首字母大小写来决定访问权限
    pkoukk
        2
    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
        3
    chaleaoch  
    OP
       2021-09-14 17:54:34 +08:00
    @pkoukk 大佬我的意思是说:

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

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

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

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

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

    如果是 python 可以通过 property 解决. 如果是 Go 似乎没有什么好的办法, 也许我不知道.
    chaleaoch
        8
    chaleaoch  
    OP
       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
        9
    cyrivlclth  
       2021-09-14 19:24:03 +08:00   ❤️ 1
    如果是简单的 Set,就是一个等号,那不如就用公有的
    如果是简单的 Get,就是一个 return,那不如就用公有的
    如果是无所谓使用方能不能修改的,那不如就用公有的
    你没发现 Java 里面的 get set 方法大多都是一句话吗?这种除了遵循规范,有什么实际意义呢?而 go 没有这种规范( kotlin 也没有这种规范,因为大家都觉得太啰嗦了)
    当然也不是没有 get set 的情况,比如你的属性值需要计算得出,而不是简单的=,那就需要 get 和 set 方法了。但是私有之后的字段,序列化又成问题了,你又得写 Marshall 和 Unmarshall 方法。。。
    tyx1703
        10
    tyx1703  
       2021-09-14 19:59:03 +08:00   ❤️ 1
    我觉得如果需要检查值或者重构时应该用 get/set,没这个需求不如直接设置字段来的方便
    Ansen
        11
    Ansen  
       2021-09-14 20:09:24 +08:00
    首字母大写为公有外部可调用,小写私有仅内部调用
    Mitt
        12
    Mitt  
       2021-09-15 00:38:28 +08:00 via iPhone
    getter setter 的意义就是方便未来修改和重构以及增加触发器,否则直接公开字段更实用
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   996 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 22:16 · PVG 06:16 · LAX 14:16 · JFK 17:16
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.