(1) 值类型: 基本类型 + struct
(2) 引用类型:map, slice,chan 这三个(make可以创建内存的)
(3)指针类型:很多,new(类型)
var声明
值类型:分配内存空间,并赋该类型的零值
引用类型、指针:不分配内存,默认nil,赋值会报错
new
返回一个指向该类型的指针
func new(Type) *Type
底层调用的是runtime.newobject申请内存空间
func newobject(typ *_type) unsafe.Pointer {
return mallocgc(typ.Size_, typ, true)
}
make
返回值是类型的本身,并初始化零值。仅支持 slice、map、channel 三种引用类型的内存创建
注意:这三种类型都是引用类型,他们本身也是指针,故返回类型本身,底层也是指针
func make(t Type, size ...IntegerType) Type
makeslice申请内存调用的也是mallocgc分配内存,底层返回point指针
func makeslice(et *_type, len, cap int) unsafe.Pointer {
mem, overflow := math.MulUintptr(et.Size_, uintptr(cap))
if overflow || mem > maxAlloc || len < 0 || len > cap {
mem, overflow := math.MulUintptr(et.Size_, uintptr(len))
if overflow || mem > maxAlloc || len < 0 {
panicmakeslicelen()
}
panicmakeslicecap()
}
return mallocgc(mem, et, true)
}
make map底层是makemap_small,返回hmap 指针,分配内存用new
func makemap(t *maptype, hint int, h *hmap) *hmap {
// 初始化
if h == nil {
h = new(hmap)
}
h.hash0 = fastrand()
// 计算桶大小
B := uint8(0)
for overLoadFactor(hint, B) {
B++
}
h.B = B
// 分配内存,初始化哈希表
// if B == 0, 后面再分配,即懒惰分配
// 如何hint很大,需要花费一些时间.
if h.B != 0 {
var nextOverflow *bmap
h.buckets, nextOverflow = makeBucketArray(t, h.B, nil)
if nextOverflow != nil {
h.extra = new(mapextra)
h.extra.nextOverflow = nextOverflow
}
}
return h
}
make chan底层是makechan,返回hchan 指针,分配内存用mallocgc
func makechan(t *chantype, size int) *hchan {
elem := t.Elem
mem, overflow := math.MulUintptr(elem.Size_, uintptr(size))
var c *hchan
switch {
case mem == 0:
// Queue or element size is zero.
c = (*hchan)(mallocgc(hchanSize, nil, true))
// Race detector uses this location for synchronization.
c.buf = c.raceaddr()
case elem.PtrBytes == 0:
// Elements do not contain pointers.
// Allocate hchan and buf in one call.
c = (*hchan)(mallocgc(hchanSize+mem, nil, true))
c.buf = add(unsafe.Pointer(c), hchanSize)
default:
// Elements contain pointers.
c = new(hchan)
c.buf = mallocgc(mem, elem, true)
}
c.elemsize = uint16(elem.Size_)
c.elemtype = elem
c.dataqsiz = uint(size)
lockInit(&c.lock, lockRankHchan)
return c
}
总结
- var是声明,可能分配内存,也可能没有,make和new都是分配内存,make 即分配内存,也初始化内存。new只是将内存清零,并没有初始化内存。
- make只能用来分配及初始化类型为slice,map,channel的数据;new可以分配任意类型的数据。