golang变量var new make源码[只有关键代码]

(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可以分配任意类型的数据。
  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值