Idiomatic naming convention for exported struct and getter for the whole struct in Go

huangapple go评论82阅读模式
英文:

Idiomatic naming convention for exported struct and getter for the whole struct in Go

问题

当我有一个如下所示的结构体时:

// user.go
package user

type User struct {
    ID   int
    Name string
    // 其他字段
}

func NewUser() User {
    return User{ID: 1+1}
}

// 对于用户列表,可以这样做:
func Users() []User {
    // ...
    // 返回用户列表
}

// 但是对于单个用户,命名一个getter的惯用方式是什么?
// Getter 1
func GetUser(id) User {
    // 返回具有提供的id的用户
}

// Getter 2
func Get(id) User {
    // 返回具有提供的id的用户
}

// Getter 3
func ByID(id) User {
    // 返回具有提供的id的用户
}

// Getter 4
func OfID(id) User {
    // 返回具有提供的id的用户
}

在另一个包中,可以这样使用它:

package somepackage

import "user"

func doStuff() {
    u := user.NewUser()
    // 做一些操作
}

func doOtherStuff() {
    users = user.Users()
    for _, u := range users {
        // 做其他操作
    }
}

func checkUser(userID int) {
    // 获取具有`userID` id的用户
    // 这样做?:
    u := user.GetUser(userID)

    // 还是这样做?:
    u := user.Get(userID)

    // 或者?:
    u := user.ByID(userID)

    // 或者?:
    u := user.OfID(userID)
}

当然,我希望能够像这样使用:

u.User(id)

但是由于结构体使用了名称User,所以这是不可能的。

那么,在这种情况下,命名一个getter的惯用方式是什么?或者我应该将结构体重命名为其他名称(我不太喜欢这样做)?

英文:

When I have a struct like the following:

// user.go
package user

type User struct {
    ID   int
    Name string
    // other fields
}

func NewUser() User {
    return User{ID: 1+1}
}

// for user list I can do it like this:
func Users() []User {
    // ...
    // return list of users
}

// But for sing user, what is the idiomatic way to name a getter here?
// Getter 1
func GetUser(id) User {
    // return the user that has the provided id
}

// Getter 2
func Get(id) User {
    // return the user that has the provided id
}

// Getter 3
func ByID(id) User {
    // return the user that has the provided id
}

// Getter 4
func OfID(id) User {
    // return the user that has the provided id
}

In another package I can use it like so:

package somepackage

import "user"


func doStuff() {
    u := user.NewUser()
    // do stuff
}

func doOtherStuff() {
    users = user.Users()
    for _, u := range users {
        // do other stuff
    }
}

func checkUser(useID int) {
    // Get the user of the `userID` id
    // this way?:
    u := user.GetUser(useID)

    // or this way?:
    u := user.Get(userID)

    // or?:
    u := user.ByID(userID)

    // or?:
    u := user.OfID(userID)
}

Off course I'd like to use something like:

u.User(id)

But that is not possible as the name User is used by the struct.

So what is the idiomatic way to name a getter in this case? Or should rename the struct to something else which I prefer not to?

答案1

得分: 1

根据Effective Go的建议,user包的代码可以如下所示:

package user

type (
  User struct {
    ID   int
    Name string
    // 其他字段
  }
  
  Users []User
}

// New 创建新的用户。
func New() User {
    // 初始化用户结构。
    return User{ID: 1 + 1}
}

// AdminUsers 返回具有管理员权限的用户。
func AdminUsers() Users {
   return Users{....}
}

func (l Users) Find(id int) (User, bool) {
  for i := range l {
    if l[i].ID == id {
       return l[id], true
    }
  }
  return User{}, false
}

我将NewUser重命名为New,因为后缀"User"在这里重复了包名。

Users函数在这里没有带来任何价值。据我理解,它返回一个列表,但名称并没有说明拥有该列表的目的。我用Users类型替换了它,并添加了一个通过ID在该列表中查找用户的方法,以及一个示例的AdminUsers函数,该函数返回一个管理员用户列表(实际上,它可能是一个存储库,并且每次都会从数据库中获取整个列表)。

最后一部分是getter,在我看来,在这里是没有用的,因为getter将返回与手头上的用户完全相同的用户。示例:

u := user.New()
u1 := u.User()
// u1 == u
英文:

Taking into account what is suggested by Effective Go the user package code could look like this:

package user

type (
  User struct {
    ID   int
    Name string
    // other fields
  }
  
  Users []User
}

// New creates new User.
func New() User {
    // Initialize User structure.
    return User{ID: 1 + 1}
}

// AdminUsers returns users with admin privileges.
func AdminUsers() Users {
   return Users{....}
}

func (l Users) Find(id int) (User, bool) {
  for i := range l {
    if l[i].ID == id {
       return l[id], true
    }
  }
  return User{}, false
}

I renamed NewUser to New as the user suffix duplicates the name of package here.

The Users function does not bring any value here. As i understand it returns some list but the name does not tells what is the purpose of having this list. I replaced it with Users type with a method for finding user on this list by id and example AdminUsers function which returns a list of admin user (in practice it will probably be repository and you will grab the whole list from the database every time).

The last part is the getter, which in my opinion is useless here, because getter will return exactly the same User as what you have in hand. Example:

u := user.New()
u1 := u.User()
// u1 == u

huangapple
  • 本文由 发表于 2021年8月7日 16:54:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/68690852.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定