func main() {
v := []int{1, 2, 3}
for i:= range v {
v = append(v, i)
}
}
//结果如下
[1 2 3 0 1 2]
遍历slice的时候会先获取slice的长度作为循环次数,在遍历过程中添加的元素不会被遍历到,map插入数据的位置是随机的,所以遍历过程中新插入的数据不能保证遍历到。
type student struct {
Name string
Age int
}
func main() {
//m := make(map[string]*student)
stus := []student{
{Name: "zhou", Age: 24},
{Name: "li", Age: 23},
{Name: "wang", Age: 22},
}
for _, stu := range stus {
stu = student{}
fmt.Println(stu)
}
fmt.Println(stus)
}
{ 0}
{ 0}
{ 0}
[{zhou 24} {li 23} {wang 22}]
在forrange的过程中,数据会进行一次拷贝,我们如果直接对拷贝的数据进行操作是无法改变原来的数据的。那如果我们想要改变切片中的数据的话,我们应该怎么做?
方案一:根据索引进行更新,对第二个参数进行忽略
type student struct {
Name string
Age int
}
func main() {
//m := make(map[string]*student)
stus := []student{
{Name: "zhou", Age: 24},
{Name: "li", Age: 23},
{Name: "wang", Age: 22},
}
for i, _ := range stus {
stus[i] = student{}
}
fmt.Println(stus)
}
//结果为[{ 0} { 0} { 0}]
方案二:使用切片指针
type student struct {
Name string
Age int
}
func main() {
//m := make(map[string]*student)
stus := []*student{
{Name: "zhou", Age: 24},
{Name: "li", Age: 23},
{Name: "wang", Age: 22},
}
for _, value := range stus {
value = &student{"z",1}
fmt.Println(value)
}
for i := 0; i < len(stus); i++ {
fmt.Println(stus[i])
}
}
//结果如下
&{z 1}
&{z 1}
&{z 1}
&{zhou 24}
&{li 23}
&{wang 22}
在这段代码里面,value是值拷贝,拷贝的是一个指针,我们直接把该指针指向了一个另外一个地址,&student{"z",1},所以原来的值是不会进行改变的。
下面是使用切片指针的正确用法
type student struct {
Name string
Age int
}
func main() {
//m := make(map[string]*student)
stus := []*student{
{Name: "zhou", Age: 24},
{Name: "li", Age: 23},
{Name: "wang", Age: 22},
}
for _, value := range stus {
value.Name = "大子杰"
}
for i := 0; i < len(stus); i++ {
fmt.Println(stus[i])
}
}
&{大子杰 24}
&{大子杰 23}
&{大子杰 22}
value是值拷贝,但是拷贝的是一个指针,该指针指向底层数组和stus切片指向的底层数组是相同的。
package main
import "fmt"
type Customer struct {
ID string
Balance float64
}
type Store struct {
Customers map[string]*Customer
}
func main() {
s := &Store{Customers: map[string]*Customer{}}
s.storeCustomers([]Customer{
{ID: "1", Balance: 10},
{ID: "2", Balance: -10},
{ID: "3", Balance: 0},
})
for i, v := range s.Customers {
fmt.Printf("id=%s,customer=%+v\n", i, v)
}
}
func (s *Store) storeCustomers(customers []Customer) {
//customer是一份拷贝,这份拷贝的地址只是被创建了一次,地址是固定的
for _, customer := range customers {
s.Customers[customer.ID] = &customer
}
}
//结果如下:
id=1,customer=&{ID:3 Balance:0}
id=2,customer=&{ID:3 Balance:0}
id=3,customer=&{ID:3 Balance:0}