对深浅拷贝的认识,对函数中修改切片影响原有切片的原因分、切片append原理、for…range原理简单分析。



文章目录

  • 深浅拷贝
  • 函数中修改切片值影响原有切片的原因分析
  • 切片append函数分析
  • for...range分析


深浅拷贝

浅拷贝:仅仅拷贝的是变量的值,没有对指向的空间进行任何拷贝。比如指针传参数,赋值,函数返回值(不开辟新空间)

深拷贝:将原有的变量的空间全部拷贝一份。(开辟新空间)

函数中修改切片值影响原有切片的原因分析

分析:函数中操作切片,原有切片的值会修改。slice切片底层源码就是结构体,底层结构有一个指针,这个指针直接指向存储区域。

//切片部分源码
type slice struct{
    array unsafe.Pointer//指针,函数传参,此时就是浅拷贝
    len int 
    cap int
}

map本质是个结构体指针类型,所以map同样作为参数也可以修改元素。

切片append函数分析

分析:函数中append函数追加切片,原有切片的值不会修改。调用函数,函数中的append函数进行追加数据,原有的切片全部初始化为0,无法追加,需要进行扩容,就会深拷贝,重新开辟新的空间进行追加数据,新存储区域比原切片大。

//切片部分源码
type slice struct{
    array unsafe.Pointer//指向新区域
    len int 
    cap int
}

for…range分析

  1. 作用:用于遍历容器类型的数据,例如数组、切片、map等。
  2. range的本质是一个函数方法,使用时候可以加括号使用。函数重新开辟空间进行操作。
  3. 修改range得到后的value,不影响原始切片或者数组。
func main(){
    v := [3]int{1,2,3}
    for i,value := range (v){//对形参进行遍历
        v[i] = 3
        fmt.Println("value:",value)//1,2,3
    }
    fmt.Println("v:",v)//3,3,3
}
//修改range得到后的value,不影响原始切片或者数组。
type Student struct{
    Name string
    Age int
}
func main(){
    //定义一个student类型切片
    stu1 := Student("MrWang",100)
    stu2 := Student("MrWang",100)
    stu3 := Student("MrWang",100)
    v := []Student{stu1,stu2,stu3}
    //循环遍历切片
    for _,value := range v{
        value.Age = value.Age + 1000//对每个人的年龄进行更新
    }
    //打印切片的值
    fmt.Println(v)//初始化的值,而不是修改后的值
}