go 大小写对导出的影响 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
yujianwjj
V2EX    Go 编程语言

go 大小写对导出的影响

  •  
  •   yujianwjj 2023-12-19 17:07:47 +08:00 2198 次点击
    这是一个创建于 732 天前的主题,其中的信息可能已经有所发展或是发生改变。
    package inner type inner struct { I int } func New() inner { return inner{I: 1} } 
    package outter import ( "testing" ) func TestGet(t *testing.T) { i := inner.New() t.Log(i.I) } 

    inner 是小写,理论上不应该被外部能访问,但是通过一个大写的函数,却把它暴露出来了。今天第一次看到这个写法,有点惊讶。

    之前我一般都是下面两种写法:

    package inner type Inner interface { Get() int } type inner struct { i int } func (i *inner) Get() int { return i.i } func New() Inner { return &inner{i: 1} } 
    package inner type Inner struct { I int } func New() Inner { return Inner{I: 1} } 
    12 条回复    2023-12-19 18:21:19 +08:00
    songray
        1
    songray  
       2023-12-19 17:09:58 +08:00
    bro, 这就是闭包.
    lilei2023
        2
    lilei2023  
       2023-12-19 17:13:06 +08:00
    虽然不太懂,感觉类似闭包
    body007
        3
    body007  
       2023-12-19 17:54:30 +08:00
    复制某个 GPT 的回答。

    非导出类型包含导出字段的应用场景是合法的。这种情况通常出现在需要将结构体值传递给其他包以进行处理的情况下。为了让其他包能够访问字段,这些字段必须是导出的,但结构体类型本身可以保持为非导出。

    举个例子,假设你想要生成一个 JSON 响应。你可以创建一个非导出的结构体,然后为了能够使用 `encoding/json` 包,结构体的字段必须是导出的。例如:

    ```go
    type response struct {
    Success bool `json:"success"`
    Message string `json:"message"`
    Data string `json:"data"`
    }

    func myHandler(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json;charset=")
    resp := &response{
    Success: true,
    Message: "OK",
    Data: "some data",
    }
    if err := json.NewEncoder(w).Encode(resp); err != nil {
    // 处理错误
    }
    }
    ```

    在这个例子中,`response` 结构体是非导出的,但它包含了导出的字段。这使得我们可以在 `myHandler` 函数中创建 `response` 结构体的实例,并将其传递给 `encoding/json` 包来生成 JSON 响应。

    总的来说,非导出类型包含导出字段的应用场景通常出现在需要将结构体值传递给其他包以进行处理的情况下。
    zizon
        4
    zizon  
       2023-12-19 17:56:06 +08:00
    因为 inner.New 是 exported 的.

    类似于 func New() interface{}

    加上导出不导出本来就是个编译器的约束.
    所以 i.I 也是可以的(I exported).

    你可以去提个 issue 争议下算不算 bug...
    zizon
        5
    zizon  
       2023-12-19 17:58:28 +08:00
    说可以是 bug 的原因是它形式上略不同于
    func New() interface{}

    因为有一个编译期确切的返回类型.
    zizon
        6
    zizon  
       2023-12-19 18:00:55 +08:00
    说不是 bug 的原因在于它算是一种 feature.

    需要暴露一个类型/接口,但又不想添加显式的约束(interface type/struct type).
    同时又不想给个没有类型约束的 interface{}.

    所以等价于一个 public 的接口返回一个不可修改/不可外部构造的类型.
    nagisaushio
        7
    nagisaushio  
       2023-12-19 18:08:43 +08:00
    @body007 你这回答和楼主的问题没有关系,楼主没有在问和字段相关的内容。建议不要瞎贴 GPT 的内容,会被站长枪毙。
    body007
        8
    body007  
       2023-12-19 18:12:43 +08:00
    @nagisaushio 就是要讨论字段 I 被导出,外部可以调用,而 inner 类型不是导出的情况,我只是列出了一种场景吧。
    thevita
        9
    thevita  
       2023-12-19 18:15:20 +08:00
    不能导出的是 inner 这个类型

    func New() inner {} , 这个函数是 导出的, 这里的可以理解成一个复合类型

    就像

    struct Struct {
    inner inner
    }

    这个 Struct 被导出了,但它作为一个复合类型,内部引用了 inner 一样.
    leonshaw
        10
    leonshaw  
       2023-12-19 18:18:35 +08:00
    导出不导出指的是 identifier
    kiripeng
        11
    kiripeng  
       2023-12-19 18:19:44 +08:00
    写成函数是为了做约束,比如 邮件不愿意外面的得到准确做了模糊处理 xxx**@gmail.com
    hxtheone
        12
    hxtheone  
       2023-12-19 18:21:19 +08:00 via iPhone
    虽然这个做法能被编译通过而且也有一定的使用场景, 但是感觉是因为支持闭包留下的一个口子, 如果开了 linter 的话都会被提醒一句 'exported func Outer returns unexported type main.inner, which can be annoying to use’, 像我这种强迫症肯定是会把 inner 改掉的
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     982 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 18:31 PVG 02:31 LAX 10:31 JFK 13:31
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86