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

请教个 go type 的问题

  •  
  •   hujianxin · 2018-10-01 23:48:48 +08:00 · 2582 次点击
    这是一个创建于 2244 天前的主题,其中的信息可能已经有所发展或是发生改变。

    各位好, 我定义了个这种类型:type ObjectMetadata http.Header

    那么为什么 ObjectMetadata 的对象无法使用 Get 方法呢?

    谢谢

    8 条回复    2018-10-02 13:06:09 +08:00
    hst001
        1
    hst001  
       2018-10-02 00:18:44 +08:00
    当你 type A B 的时候,你定义了一个新类型 A,虽然底层类型是 B,当时 A 和 B 是两个不一样的类型,如果要调用 B 的方法,要先把 A 转成 B:B(A).Method()
    heimeil
        2
    heimeil  
       2018-10-02 00:18:57 +08:00   ❤️ 2
    type ObjectMetadata struct { http.Header }
    or
    type ObjectMetadata = http.Header

    type T N 是定义一个新类型,只继承了内存布局,并没有继承方法集
    type T struct { N } 是在 T 里嵌入 N 并继承方法集
    type T = N 是类型别名,完全等于原类型,只是起了个别名而已,Go1.9 才新加的特性
    hst001
        3
    hst001  
       2018-10-02 00:19:32 +08:00
    如果你想继承 B 的方法,应该内嵌 B 类型
    hujianxin
        4
    hujianxin  
    OP
       2018-10-02 00:26:22 +08:00
    @hst001 @heimeil 谢谢二位细心地讲解,我有所领悟了。

    但是目前 组合和类型别名 这两种实现方式稍微有点遗憾呢。

    如果使用类型别名的话,我就无法给 ObjectMetadata 这个类型定义一个新方法了。

    如果是使用组合嵌入的话,在构造这个 ObjectMetadata 对象的时候,就会把 http.Header 的概念暴露出来了。

    请问二位有好的解决方案吗?
    heimeil
        5
    heimeil  
       2018-10-02 00:36:51 +08:00
    你是只想要 Get 方法吗?那定义一个新类型,你再自己定义一个 Get 就行了,type T N 就像#1 说的那种显示类型转换再调用,还可以像 type T struct { h H }定义成 struct 的私有成员就不会暴露出来了。
    hujianxin
        6
    hujianxin  
    OP
       2018-10-02 00:38:48 +08:00
    @heimeil 嗯嗯,有道理,谢谢
    scnace
        7
    scnace  
       2018-10-02 11:06:24 +08:00 via Android
    你的意思应该就是 type T struct { http.Header}吗 这样 http.Header 不应该暴露的 T 也不会暴露 http.Header 暴露出来的从语义上来说 T 也是应该需要暴露的吧🤔
    hujianxin
        8
    hujianxin  
    OP
       2018-10-02 13:06:09 +08:00
    @scnace 我的意思是这样的

    暴露给用户一个 ObjectMetadata 概念,但是不让他们接触到 ObjectMetadata 实际上是一个 http.Header 类型的。

    如果使用 type ObjectMetadata struct { http.Header}这样的话,那么在新建 ObjectMetadata 对象的时候只能这样:

    ```
    om := ObjectMetadata{http.Header{}}
    ```

    当然,可以给用户提供一个 NewObjectMetadata 的函数来创建 ObjectMetadata 对象,但是一旦这个类型暴露出来,http.Header 也就难免的暴露出来了。

    不过这些问题应该不大
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2228 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 00:58 · PVG 08:58 · LAX 16:58 · JFK 19:58
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.