golang return first field from struct

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

golang return first field from struct

问题

我正在尝试根据一个属性(可以是user_id、email或name)返回所有用户信息。

u := User{
    Email: "goda@go.com",
}
k := User{
    Name: "john",
}

ReturnUserInfo(u)
ReturnUserInfo(k)

我调用这个函数,传入一个只有一个字段的User结构体。然后我想解析这个字段,而不需要明确地指定email。最后,通过传递一个隐式字段(user_id或email等),我获取用户信息。

func ReturnUserInfo(u User) (y User) {
    // 从u中检索第一个字段,并将它们设置为field和value。
    // 不明确地声明 field := email, value := u.Email

    db, _ := sql.Open("mysql", "root:password@/users")
    _ := db.QueryRow("SELECT user_id, name, email FROM users WHERE ? = ?", field, value).Scan(
        &u.User_id, &u.Name, &u.Email)
    y = User{
        User_id: u.User_id,
        Name:    u.Name,
        Email:   u.Email,
    }
    return y
}

我不确定在Golang中是否能够这样做,但我正在创建这个函数,这样我就不必明确告诉Go查找特定的属性来返回用户的信息。

英文:

I am trying to return all user information given ONE attribute which can either be user_id, email, or name.

u := User{
 Email: "goda@go.com"
 })
k := User {
Name: "john"
}
    
ReturnUserInfo(u)
ReturnUserInfo(k)

I invoke the function passing a User struct with only one field. Then I want to parse the field without EXPLICITLY saying the email. In the end I get the user information by passing an implicit field (user_id OR email etc.)

func ReturnUserInfo(u User) (y User){
	// Retrieve first field from u and set them to field and value.
    // NOT explicitly stating field := email, value := u.Email

	db, _ := sql.Open("mysql", "root:password@/users")
	_ := db.QueryRow("SELECT user_id, name, email FROM users WHERE ? = ?", field, value).Scan(
		&u.User_id, &u.Name, &u.Email)
	y = User{
		User_id: u.User_id,
		Name: u.Name,
		Email: u.Email,
	}
	return y

}

I am not sure if I am able to do this in Golang, but I am creating this function so I do not have to explicitly tell Go to look for a particular attribute to return a user's information.

答案1

得分: 0

你想要的东西有几个不好或至少有争议的设计决策。

1)SQL语句中你不能使用"WHERE ? = ?"。列名不能用?替换,只能用值替换。这不是由golang引起的,而是由数据库引起的,因为当它获取请求时,会创建一个获取数据的计划(使用哪个索引或全表扫描等)。

这意味着你必须为每个要在WHERE子句中使用的列创建不同的查询字符串。可以像这样:

func GetUserInfoByColumn(field string) (*User, error) {
    query := fmt.Sprintf("SELECT user_id, name, email FROM users WHERE %s = ?", field)
    var u User
    err := db.QueryRow(query, value).Scan(&u.User_id, &u.Name, &u.Email)
    if err != nil {
        return nil, err
    }
    return &u, nil
}

比这更有效的方法是使用闭包,在那里创建查询。

2)db.QueryRow看起来是另一个问题。只有在你确定只有一行与你的条件匹配时才能使用它。如果你不太确定,请使用db.Query。

3)在Go中,你可以使用反射来获取结构体中所有项的名称。但如果你的结构体只有几个字段,这太复杂了。在我们的情况下,你可以简单地创建所有必要的函数。

4)我不明白为什么你总是尝试只填充结构体的一个字段并将过滤器放入结构体中。是否更好的做法是有更多的函数,并在代码的适当位置调用UserInfoByName或UserInfoByEmail?为什么你尝试根据字段选择一个过滤器?

英文:

What you want has several bad or at least controversary design decision.

  1. SQL statement you cannot use "WHERE ? = ?". Name of the column cannot be replaced with ?, only values can. It is not caused by golang, but by database, because when it obtain request create a plan how to obtain a data (which index use or full table scan or ...).

That means you have to create different string of query for each column, you want use in where clause. It can look something like this:

    func GetUserInfoByColumn(field string) *User, error {
query := fmt.Sprintf("SELECT user_id, name, email FROM users WHERE %s = ?", column)
    var u User
    err := db.QueryRow(query, value).Scan(&u.User_id, &u.Name, &u.Email)
    if err != nil {return nil, err}
    return &u, nil
    }

More efective than this is using a closure and create query there.

  1. db.QueryRow looks like another problem. You can use it only if you are sure, that only one row matches your criteria. If you are not so sure, please use db.Query.

  2. In go you can use reflect to get a name of all items in struct. But if your struct has only few field it is too complicated. In our case you can simple create all necessary functions very simple.

  3. I don't understand why you tries to fill always just one field of struct and put the filter into struct. Would not be better have more functions and just call UserInfoByName, or UserInfoByEmail at proper place of code? Why you tries to choose a filter accoring field?

huangapple
  • 本文由 发表于 2015年10月17日 05:00:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/33179479.html
匿名

发表评论

匿名网友

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

确定