Go for Range遍历

func main() {
    v := []int{1, 2, 3}
    for i:= range v {
        v = append(v, i)
    }
}
//结果如下
[1 2 3 0 1 2]

 遍历slice的时候会先获取slice的长度作为循环次数,在遍历过程中添加的元素不会被遍历到,map插入数据的位置是随机的,所以遍历过程中新插入的数据不能保证遍历到。

for range 中的值拷贝

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}

你可能感兴趣的:(golang,开发语言,后端)