golang 在 for 循环中追加问题
golang append issue inside a for loop
问题:
append
inside Users()
for loop below 将 users
中的最后一项添加到 userRxs []*UserResolver
3x
期望:
append
应将 users
中的每个项目添加到 userRxs []*UserResolver
// Users return all users from Db
func (r *RootResolver) Users() ([]*UserResolver, error) {
var userRxs []*UserResolver
users := r.Db.Users()
for _, u := range users {
log.Printf("userID: %s, username: %s, email: %s, password: %s", u.UserID, u.Username, u.Email, u.Password)
userRxs = append(userRxs, &UserResolver{&u})
}
log.Printf("%v", userRxs)
return userRxs, nil
}
在 for 循环中,log.Printf
打印此
userID: 0374402a-3dc4-48da-86c4-949905ccc26c, username: sunnysan, email: sunnysan@gmail.com, password: 12345678
userID: 53f21c4f-2cd8-4e67-b3e9-5ef344806230, username: sunnysan2, email: sunnysan2@gmail.com, password: 12345678
userID: 0a47d3af-03dc-4050-a028-7a41599af497, username: sunnysan3, email: sunnysan3@gmail.com, password: 12345678
for 循环后,log.Printf("%v", userRxs)
打印此
[
User {
userID: 0a47d3af-03dc-4050-a028-7a41599af497,
username: sunnysan3,
email: sunnysan3@gmail.com,
password: 12345678
}
User {
userID: 0a47d3af-03dc-4050-a028-7a41599af497,
username: sunnysan3,
email: sunnysan3@gmail.com,
password: 12345678
}
User {
userID: 0a47d3af-03dc-4050-a028-7a41599af497,
username: sunnysan3,
email: sunnysan3@gmail.com,
password: 12345678
}
]
这里是完整的文件以获取更多上下文
package main
import (
"fmt"
"log"
graphql "github.com/graph-gophers/graphql-go"
)
/*
* User GQL type
type User {
userID: ID!
username: String!
email: String!
password: String!
}
*/
// User type should match the exact shape of the schema commented above
type User struct {
UserID graphql.ID
Username string
Email string
Password string
}
// RootResolver ingests Db to run queries (getters) against it
type RootResolver struct {
*Db
}
// String prints pretty structs ie. fmt.Printf can't do it on its own
func (r *UserResolver) String() string {
return fmt.Sprintf("User{userID: %s, username: %s, email: %s, password: %+v}",
r.u.UserID, r.u.Username, r.u.Email, r.u.Password,
)
}
// Users return all users from Db
func (r *RootResolver) Users() ([]*UserResolver, error) {
var userRxs []*UserResolver
users := r.Db.Users()
for _, u := range users {
log.Printf("userID: %s, username: %s, email: %s, password: %s", u.UserID, u.Username, u.Email, u.Password)
userRxs = append(userRxs, &UserResolver{&u})
}
log.Printf("%v+", userRxs)
return userRxs, nil
}
// User returns a single user from Db
func (r *RootResolver) User(args struct{ UserID graphql.ID }) (*UserResolver, error) {
// Find user:
u, err := r.Db.User(args.UserID)
if err != nil {
// Didn’t find user:
return nil, nil
}
return &UserResolver{&u}, nil
}
// UserResolver ingests properties from User
type UserResolver struct{ u *User }
// UserID returns the userId of the user
func (r *UserResolver) UserID() graphql.ID {
return r.u.UserID
}
// Username returns the username of the user
func (r *UserResolver) Username() string {
return r.u.Username
}
// Email returns the email of the user
func (r *UserResolver) Email() string {
return r.u.Email
}
// Password returns the password of the user
func (r *UserResolver) Password() string {
return r.u.Password
}
r.Db.Users()
方法
// Users correspond to Users query from graphql
func (d *Db) Users() []User {
rows, err := d.Query("SELECT * FROM users")
Check(err, "stmt.Query")
// Create User struct for holding each row's data
var r User
// Create slice of Users for our response
users := []User{}
// Copy the columns from row into the values pointed at by r (User)
// order matters here from db table
defer rows.Close()
for rows.Next() {
err = rows.Scan(
&r.UserID,
&r.Username,
&r.Email,
&r.Password,
)
Check(err, "rows.Next")
users = append(users, r)
}
return users
}
每次迭代都会覆盖范围变量,&u
也是一样。因此,您最终会多次附加包含相同地址的 UserResolver
。您需要使用该变量的本地副本。试试这个:
for _, u := range users {
u:=u // Make a copy of the variable and redeclare it
userRxs = append(userRxs, &UserResolver{&u})
}
问题:
append
inside Users()
for loop below 将 users
中的最后一项添加到 userRxs []*UserResolver
期望:
append
应将 users
中的每个项目添加到 userRxs []*UserResolver
// Users return all users from Db
func (r *RootResolver) Users() ([]*UserResolver, error) {
var userRxs []*UserResolver
users := r.Db.Users()
for _, u := range users {
log.Printf("userID: %s, username: %s, email: %s, password: %s", u.UserID, u.Username, u.Email, u.Password)
userRxs = append(userRxs, &UserResolver{&u})
}
log.Printf("%v", userRxs)
return userRxs, nil
}
在 for 循环中,log.Printf
打印此
userID: 0374402a-3dc4-48da-86c4-949905ccc26c, username: sunnysan, email: sunnysan@gmail.com, password: 12345678
userID: 53f21c4f-2cd8-4e67-b3e9-5ef344806230, username: sunnysan2, email: sunnysan2@gmail.com, password: 12345678
userID: 0a47d3af-03dc-4050-a028-7a41599af497, username: sunnysan3, email: sunnysan3@gmail.com, password: 12345678
for 循环后,log.Printf("%v", userRxs)
打印此
[
User {
userID: 0a47d3af-03dc-4050-a028-7a41599af497,
username: sunnysan3,
email: sunnysan3@gmail.com,
password: 12345678
}
User {
userID: 0a47d3af-03dc-4050-a028-7a41599af497,
username: sunnysan3,
email: sunnysan3@gmail.com,
password: 12345678
}
User {
userID: 0a47d3af-03dc-4050-a028-7a41599af497,
username: sunnysan3,
email: sunnysan3@gmail.com,
password: 12345678
}
]
这里是完整的文件以获取更多上下文
package main
import (
"fmt"
"log"
graphql "github.com/graph-gophers/graphql-go"
)
/*
* User GQL type
type User {
userID: ID!
username: String!
email: String!
password: String!
}
*/
// User type should match the exact shape of the schema commented above
type User struct {
UserID graphql.ID
Username string
Email string
Password string
}
// RootResolver ingests Db to run queries (getters) against it
type RootResolver struct {
*Db
}
// String prints pretty structs ie. fmt.Printf can't do it on its own
func (r *UserResolver) String() string {
return fmt.Sprintf("User{userID: %s, username: %s, email: %s, password: %+v}",
r.u.UserID, r.u.Username, r.u.Email, r.u.Password,
)
}
// Users return all users from Db
func (r *RootResolver) Users() ([]*UserResolver, error) {
var userRxs []*UserResolver
users := r.Db.Users()
for _, u := range users {
log.Printf("userID: %s, username: %s, email: %s, password: %s", u.UserID, u.Username, u.Email, u.Password)
userRxs = append(userRxs, &UserResolver{&u})
}
log.Printf("%v+", userRxs)
return userRxs, nil
}
// User returns a single user from Db
func (r *RootResolver) User(args struct{ UserID graphql.ID }) (*UserResolver, error) {
// Find user:
u, err := r.Db.User(args.UserID)
if err != nil {
// Didn’t find user:
return nil, nil
}
return &UserResolver{&u}, nil
}
// UserResolver ingests properties from User
type UserResolver struct{ u *User }
// UserID returns the userId of the user
func (r *UserResolver) UserID() graphql.ID {
return r.u.UserID
}
// Username returns the username of the user
func (r *UserResolver) Username() string {
return r.u.Username
}
// Email returns the email of the user
func (r *UserResolver) Email() string {
return r.u.Email
}
// Password returns the password of the user
func (r *UserResolver) Password() string {
return r.u.Password
}
r.Db.Users()
方法
// Users correspond to Users query from graphql
func (d *Db) Users() []User {
rows, err := d.Query("SELECT * FROM users")
Check(err, "stmt.Query")
// Create User struct for holding each row's data
var r User
// Create slice of Users for our response
users := []User{}
// Copy the columns from row into the values pointed at by r (User)
// order matters here from db table
defer rows.Close()
for rows.Next() {
err = rows.Scan(
&r.UserID,
&r.Username,
&r.Email,
&r.Password,
)
Check(err, "rows.Next")
users = append(users, r)
}
return users
}
每次迭代都会覆盖范围变量,&u
也是一样。因此,您最终会多次附加包含相同地址的 UserResolver
。您需要使用该变量的本地副本。试试这个:
for _, u := range users {
u:=u // Make a copy of the variable and redeclare it
userRxs = append(userRxs, &UserResolver{&u})
}