1 回答
TA贡献1783条经验 获得超4个赞
您可以使用func Save(d interface{})这样的一种:
package main
import (
"encoding/json"
"fmt"
)
type User struct {
ID int
Name string
}
type Admin struct {
User
Level int
}
func main() {
Save(User{})
Save(Admin{})
}
func Save(d interface{}) {
body, err := json.Marshal(d)
if err != nil {
panic(err)
}
st := string(body)
fmt.Println(st)
}
输出:
{"ID":0,"Name":""}
{"ID":0,"Name":"","Level":0}
对于您的情况,请对所有类型使用此功能:
func Save(i interface{}, id int) {
data, err := json.Marshal(i)
check(err)
if id == 0 {
_, err = app.DB.Exec(`INSERT INTO users(data) VALUES ($1) `, string(data))
} else {
_, err = app.DB.Exec(`UPDATE users SET data = $1 WHERE id=$2`, string(data), id)
}
check(err)
}
并这样称呼它:
u := User{}
a := Admin{}
Save(u, u.ID)
Save(a, a.ID)
是的,这甚至简化了Save对一个参数的调用:
package main
import (
"encoding/json"
"fmt"
)
type Model interface {
ID() int
setID(int)
}
type User struct {
Id int
Name string
}
func (t User) ID() int { return t.Id }
func (t User) setID(id int) { t.Id = id }
type Admin struct {
User
Level int
}
func main() {
Save(User{})
Save(Admin{})
}
func Save(d Model) {
body, err := json.Marshal(d)
if err != nil {
panic(err)
}
st := string(body)
fmt.Println(st)
fmt.Println("ID is ", d.ID())
}
输出:
{"Id":0,"Name":""}
ID is 0
{"Id":0,"Name":"","Level":0}
ID is 0
现在您可以将这一功能用于所有类型:
func Save(i Model) {
data, err := json.Marshal(i)
check(err)
id := i.ID()
if id == 0 {
_, err = app.DB.Exec(`INSERT INTO users(data) VALUES ($1) `, string(data))
} else {
_, err = app.DB.Exec(`UPDATE users SET data = $1 WHERE id=$2`, string(data), id)
}
check(err)
}
并这样称呼它:
u := User{}
a := Admin{}
Save(u)
Save(a)
有效围棋:
吸气剂
Go 不提供对 getter 和 setter 的自动支持。自己提供 getter 和 setter 并没有错,而且这样做通常是合适的,但是将 Get 放入 getter 的名称中既不习惯也没有必要。如果您有一个名为 owner(小写,未导出)的字段,则 getter 方法应称为 Owner(大写,已导出),而不是 GetOwner。使用大写名称进行导出提供了将字段与方法区分开来的钩子。如果需要,setter 函数可能会被称为 SetOwner。这两个名字在实践中都很好读:
owner := obj.Owner()
if owner != user {
obj.SetOwner(user)
}
- 1 回答
- 0 关注
- 115 浏览
添加回答
举报