初始化

golang没有构造函数 变量声明后会零初始化(也算是RAII吧)

本文讲述不同类型变量零初始化的结果和其他初始化操作

零初始化

常量`const`

golang的常量存在一种特殊情况:无类型常量

const (
    e  = 2.71828182845904523536028747135266249775724709369995957496696763
    pi = 3.14159265358979323846264338327950288419716939937510582097494459
)
1
2
3
4

至少有256bit的运算精度open in new window

它可以赋值给有类型的变量 不过会折损精度

类型初始化备注
数值类型0complex虚部和实部都初始化为0
字符串""字符串不可变
Slice/Map/funcnil只能和nil比较
interface/channel/pointernil
struct每个成员零初始化按该表规则递归初始化各部分

new

为类型分配空间并进行零初始化 然后返回该空间地址

new 在 golang 中并不意味堆分配

func main() {
	var local int
	var nlocal = new(int)
	fmt.Printf("%p,%p", &local, nlocal) // 0xc0000bc000,0xc0000bc008
}
1
2
3
4
5

可以发现这里的地址是连续的 所以并不是new出来的在堆上 变量的存储地址由编译器决定

// 方式1
ptr := new(T)

// 方式2
var t T
ptr := &t
1
2
3
4
5
6

可以认为new(T)是 var t T; &t 的语法糖open in new window

反正变量都会零初始化 所以不知道new有什么意义

make

构造后底层数据后返回包含底层数据地址的复合结构

具体行为与传参时的复制类似

// The make built-in function allocates and initializes an object of type
// slice, map, or chan (only). Like new, the first argument is a type, not a
// value. Unlike new, make's return type is the same as the type of its
// argument, not a pointer to it. The specification of the result depends on
// the type:
//	Slice: The size specifies the length. The capacity of the slice is
//	equal to its length. A second integer argument may be provided to
//	specify a different capacity; it must be no smaller than the
//	length. For example, make([]int, 0, 10) allocates an underlying array
//	of size 10 and returns a slice of length 0 and capacity 10 that is
//	backed by this underlying array.
//	Map: An empty map is allocated with enough space to hold the
//	specified number of elements. The size may be omitted, in which case
//	a small starting size is allocated.
//	Channel: The channel's buffer is initialized with the specified
//	buffer capacity. If zero, or the size is omitted, the channel is
//	unbuffered.
func make(t Type /*builtin for any type*/, size ...IntegerType /*builtin [IntergerType Int|Uint]*/) Type

var _map = make(map[string]int)
var _slice = make([]int, _len, _cap)
var _chan = make(chan in, _buffer)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

reference