英文:
Golang: Is there any way to access the "child" struct in the "parent" struct's methods in Go's composition model?
问题
我想创建一个通用的模型结构体,嵌入到使用gorp
(https://github.com/coopernurse/gorp)在MySQL数据库中持久化对象的结构体中。据我了解,在Go中,这种组合是实现类似于强类型面向对象语言中继承的方式。
然而,我一直没有好运气,因为我想在GorpModel
结构体上定义所有的CRUD方法,以避免在每个模型中重复定义它们,但是这会导致gorp
(目前我正在使用的方式)假设我要与之交互的表名为GorpModel
,这是由于gorp
使用的反射引起的。这自然会导致错误,因为在我的数据库中没有这样的表。
有没有办法找出/使用我所在的类型(GorpModel
嵌入的超类),使下面的代码工作,或者我完全走错了方向?
package models
import (
"fmt"
"reflect"
"github.com/coopernurse/gorp"
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
type GorpModel struct {
New bool `db:"-"`
}
var dbm *gorp.DbMap = nil
func (gm *GorpModel) DbInit() {
gm.New = true
if dbm == nil {
db, err := sql.Open("mysql", "username:password@my_db")
if err != nil {
panic(err)
}
dbm = &gorp.DbMap{Db: db, Dialect: gorp.MySQLDialect{"InnoDB", "UTF8"}}
dbm.AddTable(User{}).SetKeys(true, "Id")
dbm.CreateTables()
}
}
func (gm *GorpModel) Create() {
err := dbm.Insert(gm)
if err != nil {
panic(err)
}
}
func (gm *GorpModel) Delete() int64 {
nrows, err := dbm.Delete(gm)
if err != nil {
panic(err)
}
return nrows
}
func (gm *GorpModel) Update() {
_, err := dbm.Update(gm)
if err != nil {
panic(err)
}
}
GorpModel
结构体的New
属性用于跟踪它是否是新创建的模型,以及我们是否应该在Save
上调用Update
或Insert
(目前在子User
结构体中定义)。
英文:
I want to make a generic model struct to embed in structs that will use gorp
(https://github.com/coopernurse/gorp) to persist objects in my MySQL database. It's my understanding that this kind of composition is how one accomplishes things in Go that are done with inheritance in strongly OO languages.
I haven't been having good luck, however, as I want to define all of the CRUD methods on the GorpModel
struct, to avoid repeating them in each model, but this causes gorp
(as I'm using it right now) to assume that the table I want to interact with is called GorpModel
due to the reflection that gorp
uses. Which causes errors, naturally, as I have no such table in my database.
Is there any way to figure out / use which type I'm in (the superclass which GorpModel
is embedded in) to make the below code work, or am I barking up the wrong tree altogether?
package models
import (
"fmt"
"reflect"
"github.com/coopernurse/gorp"
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
type GorpModel struct {
New bool `db:"-"`
}
var dbm *gorp.DbMap = nil
func (gm *GorpModel) DbInit() {
gm.New = true
if dbm == nil {
db, err := sql.Open("mysql", "username:password@my_db")
if err != nil {
panic(err)
}
dbm = &gorp.DbMap{Db: db, Dialect: gorp.MySQLDialect{"InnoDB", "UTF8"}}
dbm.AddTable(User{}).SetKeys(true, "Id")
dbm.CreateTables()
}
}
func (gm *GorpModel) Create() {
err := dbm.Insert(gm)
if err != nil {
panic(err)
}
}
func (gm *GorpModel) Delete() int64 {
nrows, err := dbm.Delete(gm)
if err != nil {
panic(err)
}
return nrows
}
func (gm *GorpModel) Update() {
_, err := dbm.Update(gm)
if err != nil {
panic(err)
}
}
The New
property of the GorpModel
struct is used to keep track of whether it is a newly created model, and whether we should call Update
or Insert
on Save
(which is defined in the child User
struct at the moment).
答案1
得分: 2
没有。
我不知道最佳的解决方案是什么,但是关于你试图在某种基类中实现的CRUD操作,只需将它们编写为函数即可。例如:
func Create(gm interface{}) { // 或者其他应该是什么签名
err := dbm.Insert(gm)
if err != nil {
panic(err)
}
}
英文:
> Is there any way to figure out / use which type I'm in (the superclass which GorpModel is embedded in)
No.
I don't know the best way to structure your solution, but with respect to the CRUD you're trying to implement in some kind of base class, just write them as functions. ie.
func Create(gm interface{}) { // or whatever the signature should be
err := dbm.Insert(gm)
if err != nil {
panic(err)
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论