切片元素未在 go 中更新
Slice element not updated in go
我的账户结构如下:
type Account struct {
Id string
Name string
Address string
City string
Email string
Phone string
Username string
Password string
IsActive bool
}
我还有两个函数:find
和update
。 find
函数从切片中找到某个元素,return 指向该元素的指针:
func find(accounts []Account, username string) *Account {
for _, acc := range accounts {
if acc.IsActive && acc.Username == username {
return &acc
}
}
return nil
}
更新函数更改参数中的某些字段:
func update(account *Account, name string) {
account.Name = name
}
在main
中,我尝试find
切片中的一个元素并将其存储到帐户的指针中。然后,我尝试 update
下一行中的一个字段。这就是我的 main
的样子:
func main() {
accounts := []Account{{
Id: "1",
Name: "name",
Address: "address",
City: "city",
Email: "email@email.com",
Phone: "123456789",
Username: "username",
Password: "1234",
IsActive: true,
}}
var acc *Account
acc = find(accounts, "username")
fmt.Printf("%v\n", accounts)
fmt.Println(acc)
update(acc, "updated")
fmt.Printf("%v\n", accounts)
fmt.Println(acc)
}
问题是调用update
时,切片中的元素没有更新。它只是更新存储帐户的数据。以下是 main 的输出:
// find
[{1 name address city email@email.com 123456789 username 1234 true}]
&{1 name address city email@email.com 123456789 username 1234 true}
// update
[{1 name address city email@email.com 123456789 username 1234 true}]
&{1 updated address city email@email.com 123456789 username 1234 true}
如何在store元素改变的时候更新slice里面的元素?感谢您的帮助,如有任何建议,我们将不胜感激。
在您的代码中,
func find(accounts []Account, username string) *Account {
for _, acc := range accounts {
if acc.IsActive && acc.Username == username {
return &acc
}
}
return nil
}
因为您正在迭代的切片是 []Account
类型,所以您获得的每个 acc
值都是存储在切片中的值的副本。
因此,您引用的 acc
值不是存储在切片中的值。
要防止这种行为,请使用指针切片,即:[]*Account
。
避免引用您接受的答案中演示的切片索引,您可能 运行 进入微妙之处,再次使用 []*Account
https://play.golang.org/p/ru_0v_z8E9l
package main
import (
"fmt"
)
type Account struct {
Id string
Name string
Address string
City string
Email string
Phone string
Username string
Password string
IsActive bool
}
func main() {
accounts := []Account{{
Id: "1",
Name: "name",
Address: "address",
City: "city",
Email: "email@email.com",
Phone: "123456789",
Username: "username",
Password: "1234",
IsActive: true,
}}
var acc *Account
acc = find(accounts, "username")
fmt.Println("the original data")
fmt.Printf("%#v\n", accounts)
fmt.Printf("%#v\n", acc)
fmt.Println()
fmt.Println("lets update the value pointed at the first position in the slice")
update(acc, "updated")
fmt.Printf("%#v\n", accounts)
fmt.Printf("%#v\n", acc)
fmt.Println("the item is updated in both variable, we are god so far.")
fmt.Println()
fmt.Println("increasing the length of the slice to force a backing array update")
accounts = append(accounts, Account{})
accounts = append(accounts, Account{})
accounts = append(accounts, Account{}) // ensure append function changes the backing array
fmt.Println()
fmt.Println("now lets update that f pointer again")
update(acc, "updated again") // update again
fmt.Printf("%#v\n", accounts)
fmt.Printf("%#v\n", acc)
fmt.Println("Have you spotted the issue in the Account slice at position 0 ?")
fmt.Println()
fmt.Println(`In regard to OP question: How to make the element inside the slice updated when the store element changed?`)
fmt.Println("it is a use case that fails")
}
func find(accounts []Account, username string) *Account {
for i, acc := range accounts {
if acc.IsActive && acc.Username == username {
return &accounts[i]
}
}
return nil
}
func update(account *Account, name string) {
account.Name = name
}
问题是您返回的是元素的副本而不是数组中元素的实际地址
return &acc
如下更改查找功能
func find(accounts []Account, username string) *Account {
for idx , acc := range accounts {
if acc.IsActive && acc.Username == username {
return &accounts[idx]
}
}
return nil
}
你会得到预期的回应
[{1 name address city email@email.com 123456789 username 1234 true}]
&{1 name address city email@email.com 123456789 username 1234 true}
[{1 updated address city email@email.com 123456789 username 1234 true}]
&{1 updated address city email@email.com 123456789 username 1234 true}
您可以查看更新后的代码here in go playground
我的账户结构如下:
type Account struct {
Id string
Name string
Address string
City string
Email string
Phone string
Username string
Password string
IsActive bool
}
我还有两个函数:find
和update
。 find
函数从切片中找到某个元素,return 指向该元素的指针:
func find(accounts []Account, username string) *Account {
for _, acc := range accounts {
if acc.IsActive && acc.Username == username {
return &acc
}
}
return nil
}
更新函数更改参数中的某些字段:
func update(account *Account, name string) {
account.Name = name
}
在main
中,我尝试find
切片中的一个元素并将其存储到帐户的指针中。然后,我尝试 update
下一行中的一个字段。这就是我的 main
的样子:
func main() {
accounts := []Account{{
Id: "1",
Name: "name",
Address: "address",
City: "city",
Email: "email@email.com",
Phone: "123456789",
Username: "username",
Password: "1234",
IsActive: true,
}}
var acc *Account
acc = find(accounts, "username")
fmt.Printf("%v\n", accounts)
fmt.Println(acc)
update(acc, "updated")
fmt.Printf("%v\n", accounts)
fmt.Println(acc)
}
问题是调用update
时,切片中的元素没有更新。它只是更新存储帐户的数据。以下是 main 的输出:
// find
[{1 name address city email@email.com 123456789 username 1234 true}]
&{1 name address city email@email.com 123456789 username 1234 true}
// update
[{1 name address city email@email.com 123456789 username 1234 true}]
&{1 updated address city email@email.com 123456789 username 1234 true}
如何在store元素改变的时候更新slice里面的元素?感谢您的帮助,如有任何建议,我们将不胜感激。
在您的代码中,
func find(accounts []Account, username string) *Account {
for _, acc := range accounts {
if acc.IsActive && acc.Username == username {
return &acc
}
}
return nil
}
因为您正在迭代的切片是 []Account
类型,所以您获得的每个 acc
值都是存储在切片中的值的副本。
因此,您引用的 acc
值不是存储在切片中的值。
要防止这种行为,请使用指针切片,即:[]*Account
。
避免引用您接受的答案中演示的切片索引,您可能 运行 进入微妙之处,再次使用 []*Account
https://play.golang.org/p/ru_0v_z8E9l
package main
import (
"fmt"
)
type Account struct {
Id string
Name string
Address string
City string
Email string
Phone string
Username string
Password string
IsActive bool
}
func main() {
accounts := []Account{{
Id: "1",
Name: "name",
Address: "address",
City: "city",
Email: "email@email.com",
Phone: "123456789",
Username: "username",
Password: "1234",
IsActive: true,
}}
var acc *Account
acc = find(accounts, "username")
fmt.Println("the original data")
fmt.Printf("%#v\n", accounts)
fmt.Printf("%#v\n", acc)
fmt.Println()
fmt.Println("lets update the value pointed at the first position in the slice")
update(acc, "updated")
fmt.Printf("%#v\n", accounts)
fmt.Printf("%#v\n", acc)
fmt.Println("the item is updated in both variable, we are god so far.")
fmt.Println()
fmt.Println("increasing the length of the slice to force a backing array update")
accounts = append(accounts, Account{})
accounts = append(accounts, Account{})
accounts = append(accounts, Account{}) // ensure append function changes the backing array
fmt.Println()
fmt.Println("now lets update that f pointer again")
update(acc, "updated again") // update again
fmt.Printf("%#v\n", accounts)
fmt.Printf("%#v\n", acc)
fmt.Println("Have you spotted the issue in the Account slice at position 0 ?")
fmt.Println()
fmt.Println(`In regard to OP question: How to make the element inside the slice updated when the store element changed?`)
fmt.Println("it is a use case that fails")
}
func find(accounts []Account, username string) *Account {
for i, acc := range accounts {
if acc.IsActive && acc.Username == username {
return &accounts[i]
}
}
return nil
}
func update(account *Account, name string) {
account.Name = name
}
问题是您返回的是元素的副本而不是数组中元素的实际地址
return &acc
如下更改查找功能
func find(accounts []Account, username string) *Account {
for idx , acc := range accounts {
if acc.IsActive && acc.Username == username {
return &accounts[idx]
}
}
return nil
}
你会得到预期的回应
[{1 name address city email@email.com 123456789 username 1234 true}]
&{1 name address city email@email.com 123456789 username 1234 true}
[{1 updated address city email@email.com 123456789 username 1234 true}]
&{1 updated address city email@email.com 123456789 username 1234 true}
您可以查看更新后的代码here in go playground