My API server accept post request and the request body is JSON,so I create two struct object to accept JSON string and persist it into database.But everytime I accept a request I need create the struct object over and over again,I try to clear the struct instead of recreate it.And the demo code like this following:
//The two struct
type Card struct {
Number string
Type string
}
type Person struct {
Name string
Cards []Card
}
var p Person
//parse JSON to the struct object
func init() {
str := `{"name":"aaa","cards":[{"number":"1","type":"visa"},{"number":"2","type":"mastercard"}]}`
json.Unmarshal([]byte(str), &p)
}
func PersistToDatabase() {
var err error
tx, err := db.Begin()
if err != nil {
return
}
defer func() {
if err != nil && tx != nil {
if err := tx.Rollback(); err != nil {
return
}
}
}
finish := make(chan bool)
stmt1, err := tx.Prepare(`insert into tb1(name) values(?)`)
if err != nil {
panic(err.Error())
}
defer stmt1.Close()
stmt2, err := tx.Prepare(`insert into tb2(name, num, type) values(?, ?, ?)`)
if err != nil {
panic(err.Error())
}
defer stmt2.Close()
go func() {
defer func() { finish <- true }()
if _, err = stmt1.Exec(p.name); err != nil {
log.Println("stmt1.Exec: ", err.Error())
return
}
for _, x := range p.Cards {
if _, err = stmt2.Exec(p.name, x.Number, x.Type); err != nil {
log.Println("stmt2.Exec: ", err.Error())
return
}
}
}
<-finish
//clear struct object
p.Name = ""
p.Cards = nil //have anything do this better?
}
In the code bottom I clear the Name element but let the Cards element to be nil
,how can I do better? And do my databases operation have any problem?
A struct is not an object[1]. While fundamentally they're both mishmashes of ordered data in some way or another, a struct is effectively just a list of variables. No constructor is called. No memory beyond that of its member elements is allocated, and it's not allocated in any special place. (Granted this probably isn't too expensive even in most OO languages, optimizers are pretty cool sometimes) If I have
type A struct {
I int
S string
}
var MyA A
It's not really substantially different from
var (
I int
S string
)
Writing the zero struct of a type MyA = A{}
is effectively equivalent to doing MyA.I = 0; MyA.S = ""
which is, in turn, effectively equivalent to I = 0; S = ""
. There should be no (significant) performance overhead doing any of the above.
This doesn't mean structs aren't useful. They're exceptionally useful, conceptually, for defining methods on, for filling in data such as in cases like JSON. But what they're not is significantly different. Finally, and this is the most important thing, is there a significant performance bottleneck you have profiled in this block of code? If not (and I suspect not), don't worry about it, it's probably fine. :)
[1] Java or C#-style object, which are theoretically (even if not in practice) more expensive. Not C++ objects which are different (and more like Go structs).