扩展Golang中的包结构体

29
在 Golang 中是否可能扩展结构体(类似于其他语言中的扩展类,并将其与旧函数一起使用)?
我有一个类型为 SetSlackServiceOptions 的 https://github.com/xanzy/go-gitlab/blob/master/services.go#L287
package gitlab

// SetSlackServiceOptions struct
type SetSlackServiceOptions struct {
    WebHook  *string `url:"webhook,omitempty" json:"webhook,omitempty" `
    Username *string `url:"username,omitempty" json:"username,omitempty" `
    Channel  *string `url:"channel,omitempty" json:"channel,omitempty"`
}

我希望在我的自定义包中为类型添加一些字段。我能不能这样做,以便我可以使用这个我的新类型调用函数SetSlackService?

package gitlab

func (s *ServicesService) SetSlackService(pid interface{}, opt *SetSlackServiceOptions, options ...OptionFunc) (*Response, error) {
    project, err := parseID(pid)
    if err != nil {
        return nil, err
    }
    u := fmt.Sprintf("projects/%s/services/slack", url.QueryEscape(project))

    req, err := s.client.NewRequest("PUT", u, opt, options)
    if err != nil {
        return nil, err
    }

    return s.client.Do(req, nil)
}

https://github.com/xanzy/go-gitlab/blob/266c87ba209d842f6c190920a55db959e5b13971/services.go#L297

编辑:

我想将自己的结构传递到上面的函数中。这是gitlab包中的函数,我想扩展http请求。


2
您可以将现有的结构体嵌入到自己的结构体类型中:https://golang.org/ref/spec#Struct_types - abhink
请包含一个最小、完整和可验证的示例。您应该在问题本身中显示所有(或大部分)所需的信息,而不是以链接形式呈现。同时也不清楚您想要做什么。您可以尝试将结构体嵌入到自己的类型中。 - Marc
1
你不能“扩展”一个具体类型,然后期望你的扩展可以“传递”给期望原始类型的函数。 - mkopriva
@JAttanonRadar,如果使用扩展结构体,你会如何预期它工作?比如,你添加了一个字段,用于连接时使用SSL。SetSlackService如何知道你的扩展字段?它如何能够访问它们而不需要你在该函数本身中更改代码? - Kaedys
请问您能取消踩一下吗?我去年只问了一个问题,现在无法再提问了。我已经改进了我的问题,请您将其删除。 - JAttanonRadar
显示剩余4条评论
1个回答

35

在Go语言中,结构体不能像其他面向对象编程语言中的类那样进行扩展。我们也无法在现有结构体中添加任何新字段。但是,我们可以创建一个嵌入我们需要从不同包中使用的结构体的新结构体。

package gitlab

// SetSlackServiceOptions struct
type SetSlackServiceOptions struct {
    WebHook  *string `url:"webhook,omitempty" json:"webhook,omitempty" `
    Username *string `url:"username,omitempty" json:"username,omitempty" `
    Channel  *string `url:"channel,omitempty" json:"channel,omitempty"`
}

在我们的主要包中,我们需要导入gitlab包,并将我们的结构嵌入如下:
package main

import "github.com/user/gitlab"

// extend SetSlackServiceOptions struct in another struct
type ExtendedStruct struct {
  gitlab.SetSlackServiceOptions
  MoreValues []string
}

Golang规范将结构体中的嵌入类型定义为:

声明了类型但没有显式字段名称的字段称为嵌入字段。嵌入字段必须指定为类型名称T或非接口类型名称*T的指针,并且T本身不能是指针类型。未限定的类型名称充当字段名称。

// A struct with four embedded fields of types T1, *T2, P.T3 and *P.T4
struct {
    T1        // field name is T1
    *T2       // field name is T2
    P.T3      // field name is T3
    *P.T4     // field name is T4
    x, y int  // field names are x and y
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接