20230223日志
2023年2月23日
go #
value copy #
type account struct {
balance float32
}
accounts := []account{
{balance: 100.},
{balance: 200.},
{balance: 300.},
}
for _, a := range accounts {
a.balance += 1000
}
并不会改变accounts的值, 因为在遍历时struct会被copy
- 方案1:
for i := range accounts {
accounts[i].balance += 1000
}
- 方案2:
for i := range accounts {
accounts[i].balance += 1000
}
- 方案3(关注性能时需要考虑指针的不可预测性):
accounts := []*account{
{balance: 100.},
{balance: 200.},
{balance: 300.},
}
for _, a := range accounts {
a.balance += 1000
}
Ignoring how arguments are evaluated in range loops #
s := []int{0, 1, 2}
for range s {
s = append(s, 10)
}
s := []int{0, 1, 2}
for i := 0; i < len(s); i++ {
s = append(s, 10)
}
for 循环不会停下来
ch1 := make(chan int, 3)
go func() {
ch1 <- 0
ch1 <- 1
ch1 <- 2
close(ch1)
}()
ch2 := make(chan int, 3)
go func() {
ch2 <- 10
ch2 <- 11
ch2 <- 12
close(ch2)
}()
ch := ch1
for v := range ch {
fmt.Println(v)
ch = ch2
}
range ch 也会创建新的变量指向ch, 因此 ch=ch2并不能改变range的对象
a := [3]int{0, 1, 2}
for i, v := range a {
a[2] = 10
if i == 2 {
fmt.Println(v)
}
}
range数组(not slice)会完整的copy一份数据
Ignoring the impact of using pointer elements in range loops #
type Info struct {
name string
}
s := map[string]Info{
"1": {name: "zzlion"},
"2": {name: "lixiong"},
}
a := s["1"]
a.name = "null"
fmt.Printf("%v\n", s)
map取出的值也是copy, 修改后想在原map中体现,需要重新赋值回去
type Customer struct {
ID string
Balance float64
}
type Store struct {
m map[string]*Customer
}
func (s *Store) storeCustomers(customers []Customer) {
for _, customer := range customers {
s.m[customer.ID] = &customer
}
}
range中的变量始终是同一个对象
解决方案1:
func (s *Store) storeCustomers(customers []Customer) {
for _, customer := range customers {
current := customer
s.m[current.ID] = ¤t
}
}
解决方案2:
func (s *Store) storeCustomers(customers []Customer) {
for i := range customers {
customer := &customers[i]
s.m[customer.ID] = customer
}
}
Making wrong assumptions during map iterations #
- map的key是无序的, 遍历不能保证插入的顺序
- 遍历时对map插入数据,行为是未知的