Go – 访问指针结构体的字段

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

Go - Accessing fields of a pointer struct

问题

我有一个包含敏感字段(如密码和电子邮件)的User结构体。对于一个公共的User实例,例如活动页面上的公共RSVP,我希望在我的JSON输出中排除敏感字段的显示,即使它们是空的。

根据这篇文章,我正在使用一个复合结构体来屏蔽不需要的字段。

问题:在我的数据库函数中的rows.Scan过程中,我如何正确访问复合结构体中指针结构体的字段?我得到了恐慌错误,因为找不到字段。

我的常规User结构体:

type User struct {
    ID          int    `json:"id"`
    FirstName   string `json:"firstname"`
    LastName    string `json:"lastname"`
    Registered  int    `json:"registered"`
    Email       string `json:"email"`
    Password    string `json:"password"`
    ProfilePic  string `json:"profilepic"`
}

根据上述文章中的方法,新增加的结构体:

type omit *struct {}

type PublicUser struct {
    *User
    Registered omit `json:"registered,omitempty"`
    Email      omit `json:"email,omitempty"`
    Password   omit `json:"password,omitempty"`
}

我的数据库函数中出现错误的地方:

func getUsers(db *sql.DB) ([]PublicUser, error) {

    query := `SELECT users.id, users.name_first, users.name_last
    FROM users
    ORDER BY users.name_first asc`

    users := []PublicUser{}

    rows, err := db.Query(query, e.ID)
    if err != nil {
        return nil, err
    }
    defer rows.Close()

    for rows.Next() {

        var user PublicUser

        // 错误发生在这里。似乎在PublicUser中找不到这些字段。
        // User的指针是否在我的PublicUser结构体中起作用?

        err := rows.Scan(&user.ID, &user.FirstName, &user.LastName)

        if err != nil {
            return nil, err
        }

        users = append(users, user)
    }

    return users, nil
}

我原始的JSON输出,不使用文章中的方法,只使用我的常规User结构体:

[{
    "ID": 25,
    "FirstName": "Jim",
    "LastName": "Brown",
    "Registered": 0,
    "Email": "",
    "Password": "",
    "ProfilePic": ""
},

]

期望的JSON输出:

[{
    "ID": 25,
    "FirstName": "Jim",
    "LastName": "Brown",
    "ProfilePic": ""
},

]

文章链接:https://attilaolah.eu/2014/09/10/json-and-struct-composition-in-go/

英文:

I have a User struct containing sensitive fields like password and email. For a public instance of User, for example a public RSVP on an event page, I want to exclude sensitive fields from appearing in my JSON output, even if they're blank.

Based on this article, I’m using a composite struct to mask undesired fields.

QUESTION: during rows.Scan in my database func, how do I properly access the fields of the pointer struct within the composite struct? I’m getting panic errors thrown, because fields are not being found.

My regular User struct:

type User struct {
	ID		    int `json:"id"`
	FirstName	string `json:"firstname"`
	LastName	string `json:"lastname"`
	Registered	int `json:"registered"`
	Email		string `json:"email"`
	Password	string `json:"password"`
	ProfilePic	string `json:"profilepic"`
}

The new additional structs based on the method in the article linked above:

type omit *struct {

}


type PublicUser struct {
	*User
	Registered omit `json:”registered,omitempty"`
	Email omit `json:”email,omitempty"`
	Password omit `json:"password,omitempty"`
}

My database func, where an error is occuring:

func getUsers(db *sql.DB) ([]PublicUser, error) {

	query := `SELECT users.id, users.name_first, users.name_last
	FROM users
	ORDER BY users.name_first asc`

	users := []PublicUser{}

	rows, err := db.Query(query, e.ID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	for rows.Next() {

		var user PublicUser


		// ERROR OCCURS HERE. Seems like these fields cannot be found in PublicUser.
		// Is the pointer to User working within my PublicUser struct?

		err := rows.Scan(&user.ID, &user.FirstName, &user.LastName)



		if err != nil {
			return nil, err
		}

		users = append(users, user)
	}

	return users, nil

}

My original JSON output, not using the articles' method; only using my regular User struct:

[{

    "ID": 25,
    "FirstName": "Jim",
    "LastName": "Brown",
    "Registered": 0,
    "Email": "",
    "Password": "",
    "ProfilePic": ""

},
…
]

Desired JSON output:

[{

    "ID": 25,
    "FirstName": "Jim",
    "LastName": "Brown",
    "ProfilePic": ""

},
…
]

答案1

得分: 3

问题在于当你在这里初始化变量时:

var user PublicUser

user 的所有字段都会取它们的“零”值。

由于你嵌入了一个指针,并且指针的零值是 nil,所以你不能在不出错的情况下使用该指针。

为了使其工作,你应该像这样初始化 user

user = PublicUser{ User: &User{} }

(或者不将其声明为指针)

在这里的 playground 中可以看到问题,并且按照上述描述的方式初始化变量使其工作。

https://play.golang.org/p/fXwvATUm_L

英文:

Problem there is that when you initialize the variable here:

var user PublicUser

All the fields for user take their "zero" values.

Since you are embedding a pointer, and zero value for pointers is nil, you can't use that pointer without getting an error.

In order for this to work, you should initialize user like this:

user = PublicUser{ User: &User{} }

(or don't declare it as a pointer)

See a playground here showing the issue and then initializing the variable as described above for it to work.

https://play.golang.org/p/fXwvATUm_L

huangapple
  • 本文由 发表于 2017年9月17日 20:07:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/46263893.html
匿名

发表评论

匿名网友

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

确定