"Static" method design
having a Get
function is perfectly fine; it's not unidiomatic in any way.
func (u *User) Get(id int) *User
doesn't make any sense, though, it should be func (u *User) Get(id int) error
. The one thing that you're missing is that you can define a method receiver on a pointer, and then inside of that method, dereference the pointer to overwrite what it points to.
Like this:
// Returns the user with the given id
func (u *User) Get(id int) error {
*u = User{ ... } // dereference the pointer and assign something to it
return nil // or an error here
}
and if there was any problem, return an error. Now you can say
type Getter interface {
Get(int) error
}
and so any type that defines Get(id)error
can be defined. You would then use it like this:
u := new(User)
if err := u.Get(id); err != nil {
// problem getting user
}
// everything is cool.
GetUser()
and GetPayment()
strike me as perfectly clear and idiomatic. I'm not sure what you find unclean about them.
Calling .Get()
on a struct to return another struct is the thing that strikes me as very odd, unclear, and unidiomatic.
I think this might be a case of just sticking with the idiom and trusting that you'll get used to it.
Golang does not support constructors.
Use factory functions instead (Effective Go reference). The convention is to use New
prefix:
func NewUser(id int) *User {
// Returns new User instance
}
The difference between constructor and factory function is that factory function is not "attached" to the User
struct. It's a normal function that happen to return User
while the Java/C++ like constructor is a method that modifies newly created User
object in place.