E
E
evnuh2016-08-24 19:24:14
go
evnuh, 2016-08-24 19:24:14

Marshal fields of an external structure into JSON through an internal method, or one method for all types?

So, there are no generics, I'm trying to solve the dumbest problem.
There are structures

type User struct {
   ID int
   Name string
}

type Admin struct {
   User
   Level int
}

And there are Adminmany more structures of the type, they all include User
Now I want to save them to the database, in which everything is in json. Challenge: write a save method/function once, not duplicate code for each type.
That is, I want to have one function that will:
1. Marshal the structure with all fields. That is, User will turn into {id: 1, name: "zhora"}, and Admin will turn into {id: 1, name: "gena", level: 2}
2. Save this json to the database by ID.
func (i *User) Save() {
  data, err := json.Marshal(i)
  check(err)
  if i.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), i.ID)
  }
  check(err)
}

Now we have to stupidly copy the entire function for each new type, changing only the type of the receiver. Can this be avoided?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
Никита, 2016-08-24
@evnuh

While developing on go, I realized one very important feature - you can’t think like you would do it in another language, but you have to think like in go. I do not want to go into your problem, but I think that there is a way out, for example, not to create so many structures.
On the question: you make an interface with getters / setters and 1 function that accepts this interface as an argument. You use a function, giving it a reference to a structure object.
Yes, yes, it will not work to make a method, and do it through the ass, but this is by the standards of many other languages, in Go it is the norm.
You can also play around with reflection or generators. The 1st is not a go-way, the 2nd is normal, but you have to get confused with the generation.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question