Golang重用结构体的方法

huangapple go评论86阅读模式
英文:

golang reusing methods of struct

问题

我正在学习Go语言,并且正在查看一个简单的Go示例Web应用程序:https://github.com/campoy/todo/blob/master/task/task.go

有一个结构体:

type Task struct {
    ID    int64  // 唯一标识符
    Title string // 描述
    Done  bool   // 任务是否完成
}

还有一个结构体:

// TaskManager 在内存中管理任务列表。
type TaskManager struct {
    tasks  []*Task
    lastID int64
}

TaskManager 上有一些方法:

func (m *TaskManager) Save(task *Task) error ...
func (m *TaskManager) All() []*Task...

我想知道如何将 TaskManager 泛化为 Manager,使其具有相同的方法(即:save、all、find),以便可以在不同的结构体上使用,例如 Users,它们都有 ID 字段。

我猜想构建一个通用类型的数组不适用,因为在 "save" 和 "find" 方法中都有一个 ID。

英文:

I am learning go and was looking at a simple go example web app:
https://github.com/campoy/todo/blob/master/task/task.go

Having struct:
<pre>

type Task struct {
    ID    int64  // Unique identifier
    Title string // Description
    Done  bool   // Is this task done?
} 

</pre>
and
<pre>

// TaskManager manages a list of tasks in memory.
type TaskManager struct {
    tasks  []*Task
    lastID int64
}

</pre>
There are methods on the TaskManager
func (m *TaskManager) Save(task *Task) error ...
func (m *TaskManager) All() []*Task...

I am wondering how to generalize TaskManager into Manager, so it would have these same methods (namely: save, all, find) so it can be used on different structs, for example Users, which would all have ID field.

I assume constructing an array of general type doesn't fit because there is an ID in 'save' and 'find' methods

答案1

得分: 3

Go语言目前还没有泛型(至少目前没有),但你仍然可以通过使用接口来实现你想要的功能(并不是100%)。

type Manager interface {
  Save(interface{}) error
  All() ([]interface{}, error)
}

当然,这并不是免费的,你需要在TaskManager中进行一些错误处理来实现接口,例如:

func (m *TaskManager) Save(t interface{}) error {
  task, ok := t.(Task) // 类型断言
  if !ok {
    // 返回错误:无效的输入类型
  }
  // 继续正常操作...
}

示例中的注释:

type Entry interface {
  SetID(int64)
  GetID() int64
}

type Task struct {...}

func (t *Task) SetID(id int64) {...}
func (t *Task) GetID() {...}

func (m *TaskManager) Save(e Entry) error {...}

更多关于接口的信息:

英文:

Go doesn't have generics (for now, at least), but you still can perform what you want (not 100%) by using an interface.

type Manager interface {
  Save(interface{}) error
  All() ([]interface{}, error)
}

Of course, it doesn't come for free and you need to do some error handling in your TaskManager to implement the interface, example:

func (m *TaskManager) Save(t interface) error {
  task, ok := t.(Task) // type assertion
  if !ok {
    // return error invalid input type
  }
  // do the rest as normal...
}

:Example for comment

type Entry interface {
  SetID(int64)
  GetID()int64
}

type Task struct {...}

func (t *Task) SetID(id int64) {...}
func (t *Task) GetID() {...}

func (m *TaskManager) Save(e Entry) error {...}

More info on interfaces:

答案2

得分: 0

你可能想要为具有ID的结构编写一个接口,然后将你的Manager泛化,使其操作该接口的元素,而不是特定结构的元素。

英文:

You'll probably want to write an interface for structures that have an ID, then generalize your Manager to operate on elements of that interface instead of elements of a specific struct.

huangapple
  • 本文由 发表于 2014年4月1日 09:02:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/22774990.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定