英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论