英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论