go slice深拷貝和淺拷貝

ramsey發表於2021-07-18

切片slice的資料結構

type SliceHeader struct {
    Data uintptr  //指向的引用陣列地址
    Len  int     //切片長度
    Cap  int     //切片容量
}

淺拷貝

目的切片和源切片指向同一個底層陣列,任何一個陣列元素改變,都會同時影響兩個陣列。

package main

import (
    "fmt"
    "reflect"
    "unsafe"
)

func main() {
    slice1 := []int{1,2,3,4,5}
    slice2 := slice1
    fmt.Println(slice1)
    fmt.Println(slice2)
    //同時改變兩個陣列
    slice1[1]=100
    fmt.Println(slice1)
    fmt.Println(slice2)
    fmt.Println("切片1指向的底層陣列地址:",(*reflect.SliceHeader)(unsafe.Pointer(&slice1)))
    fmt.Println("切片2指向的底層陣列地址:",(*reflect.SliceHeader)(unsafe.Pointer(&slice2)))
}

結果:

[1 2 3 4 5]
[1 2 3 4 5]
[1 100 3 4 5]
[1 100 3 4 5]
切片1指向的底層陣列地址: &{824634425392 5 5}
切片2指向的底層陣列地址: &{824634425392 5 5}

深拷貝

目的切片和源切片指向不同的底層陣列,任何一個陣列元素改變都不影響另外一個。

package  main

import (
    "fmt"
    "reflect"
    "unsafe"
)

func main() {
    slice1 := []int{1,2,3,4,5}
    slice2 := make([]int,5,5)
    copy(slice2,slice1)
    fmt.Println(slice1)
    fmt.Println(slice2)
    slice1[1]=100  //改賦值只會影響slice1
    fmt.Println(slice1)
    fmt.Println(slice2)
    fmt.Println("切片1指向的底層陣列地址:",(*reflect.SliceHeader)(unsafe.Pointer(&slice1)))
    fmt.Println("切片2指向的底層陣列地址:",(*reflect.SliceHeader)(unsafe.Pointer(&slice2)))
}

結果:

[1 2 3 4 5]
[1 2 3 4 5]
[1 100 3 4 5]
[1 2 3 4 5]
切片1指向的底層陣列地址: &{824633803040 5 5}
切片2指向的底層陣列地址: &{824633803088 5 5}
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章