"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.

Tags:

Go