Go语言中的深浅复制及基本的变量定义make,new,var

var定义,在不赋值会有默认空值

不同类型的空值

int空值是0

string空值是""而不是null或者nil

Slice空值是长度为0的Slice而不是nil,

map空值是nil,

error空值是nil,

struct空值是一个“所有成员都是空值”的空Struct而不是nil

var 定义切片,map也是有默认值的

var a []string 长度为0的string数组,可以通过append往里面加值,var a map[string]interface{}的空值是nil,所以不能通过a["a"]="b"这样的方式进行赋值。

 :=一定要初始化

new定义返回指针

a := new(int) #指向0值的指针

var a *int     #nil

a := new([]string)  #指向长度为0的string数组的指针

a := new(map[string]string)  #指向空map(nil)的指针

new的内存申请时需要注意的问题

type Student struct {
     age *int
}
func main() {
    s := new(Student)
    *(s.age) = 10 # 运行报错,s.age为nil
    fmt.Println(s.age)
}

new只会为结构体Student申请一片内存空间,不会为结构体中的指针age申请内存空间,所以引用操作就因为访问无效的内存空间而出现panic

make定义主要为channel,切片,map赋值

slice := make([]int, 0, 100)
hash := make(map[int]bool, 10)
ch := make(chan int, 5)

深浅复制问题,需要对底层结构有足够的理解

切片和map底层都是指向数组的指针, 普通的复制都是浅复制,在修改值时会影响赋值的对象

对切片和map的深复制都需要预先定义大小

对切片的深复制

func (d *Driver) SetTrips(trips []Trip) {
  d.trips = make([]Trip, len(trips))
  copy(d.trips, trips)
}

trips := ...
d1.SetTrips(trips)

// 这里我们修改 trips[0],但不会影响到 d1.trips
trips[0] = ...

对map的深复制 

type Stats struct {
  mu sync.Mutex

  counters map[string]int
}

func (s *Stats) Snapshot() map[string]int {
  s.mu.Lock()
  defer s.mu.Unlock()

  result := make(map[string]int, len(s.counters))
  for k, v := range s.counters {
    result[k] = v
  }
  return result
}

// snapshot 现在是一个拷贝
snapshot := stats.Snapshot()

只有数组可以直接复制

原文地址:https://www.cnblogs.com/peterleee/p/13890048.html