去防止重复

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

Go prevent repetition

问题

我正在开发一个 Web 应用程序,其中将包含多个模型(和相关的表),它们显然会有很多相似的方法,唯一的区别将是返回的结果类型。

示例:

package models

type User struct {...}
type Task struct {...}

func GetUser(uid string) (*User, error) {
  user := User{Id: id}
  if err := ORM.Read(&user); err != nil {
    return nil, err
  }
  return &user, nil
}

func GetTask(uid string) (*Task, error) {
  task := Task{Id: id}
  if err := ORM.Read(&task); err != nil {
    return nil, err
  }
  return &task, nil
}

等等等等...

在控制器等地方,我这样使用:

user := models.GetUser(id)

我不太确定如何在 Golang 中解决这个问题,有什么建议吗?

PS:我正在使用 Beego 框架,如果有帮助的话。

英文:

I am working on web app that is going to have multple models (and related tables) and they are obviously going to have a lot of similiar methods, the only difference is going to be the returned result type.

Examples:

package models
type User struct {...}
type Task struct {...}

func GetUser(uid string) (*User, error) {
  user := User{Id: id}
  if err := ORM.Read(&user); err != nil {
	  return nil, err
  }
  return &user, nil
}

func GetTask(uid string) (*Task, error) {
  task := Task{Id: id}
  if err := ORM.Read(&task); err != nil {
	  return nil, err
  }
  return &task, nil
}

and many many more...

in Controllers etc I am using it like:

user := models.GetUser(id)

I am not really sure how to solve this problem in Golang, any suggestions?

PS: I am using Beego Framework, if it helps.

答案1

得分: 3

将模型作为接口传递,并期望函数填充它。不需要返回它。基本上,你遵循了ORM.Read几乎完全相同的范例。

// GetByID loads the model for dst's concrete type based on its Id field using ORM.Read
func GetByID(dst interface{}) error {
    if err := ORM.Read(dst); err != nil {
        return nil, err
    }
    return nil
}

这个函数期望你创建带有已设置ID的模型。它会填充你传递进去的模型,除非返回一个error

使用方法如下:

user := User{Id: id}
err := GetByID(&user)
if err != nil {
    // 处理错误,模型未填充
}
// user 可以使用了

task := Task{Id: id}
err = GetByID(&task)
...

作为将来的参考,当你再次遇到这种情况时,注意你正在调用的库函数的函数类型。通常情况下,如果它接受一个像这样的interface{},你可以通过做完全相同的事情轻松地创建一个通用的包装器。

英文:

Pass in the Model as an interface and expect the function to populate it. No need to return it. Basically you follow almost the exact paradigm that ORM.Read does.

// GetByID loads the model for dst's concrete type based on its Id field using ORM.Read
func GetByID(dst interface{}) error {
	if err := ORM.Read(dst); err != nil {
		return nil, err
	}
	return nil
}

This function expects you to create whatever model you are getting with the ID already set. It populates the model you pass in unless it returns an error.

So usage as follows:

user := User{Id: id}
err := GetByID(&user)
if err != nil {
    // handle error. model not populated
}
// user is ready to use

task := Task{Id: id}
err = GetByID(&task)
...

As a future note, when you run into this sort of situation again, take note of the function type of the library call you are making. Often times, if it takes an interface{} like this, you can easily make a generic wrapper by doing the exact same thing.

huangapple
  • 本文由 发表于 2017年9月8日 03:57:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/46104145.html
匿名

发表评论

匿名网友

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

确定