先写用例验证,
func TestMake(t *testing.T) {
a := make([]string, 0)
fmt.Println(a == nil, a, &a, len(a), reflect.TypeOf(a), reflect.TypeOf(a).Kind())
println(a, &a, len(a))
b := new([]string)
fmt.Println(b == nil, b, *b, len(*b), reflect.TypeOf(b), reflect.TypeOf(b).Kind())
println(b, *b, len(*b))
c := make(map[string]string, 0)
fmt.Println(c == nil, c, reflect.TypeOf(c).Kind())
}
=== RUN TestMake
false [] &[] 0 []string slice
[0/0]0xe5f1a8 0xc0000040d8 0
false &[] [] 0 *[]string ptr
0xc000004150 [0/0]0x0 0
false map[] map
--- PASS: TestMake (0.00s)
PASS
从输出结果看出,make和new都分配了内存,但make返回的是值对象,new返回的是指针
为什么go要设置对象创建的两种方式:一个返回值,一个返回new。从使用的角度来,显得有些多余。但总是有原因的:
golang编译器设置了”zero value”的感念,也就是编译阶段,为你声明的变量赋予一个默认值。 官方文档说明
When storage is allocated for a variable, either through a declaration
or a call of new, or when a new value is created, either through a
composite literal or a call of make, and no explicit initialization is
provided, the variable or value is given a default value. Each element
of such a variable or value is set to the zero value for its type :
false for booleans, 0 for numeric types, “” for strings, and nil for
pointers, functions, interfaces, slices, channels, and maps. This
initialization is done recursively, so for instance each element of an
array of structs will have its fields zeroed if no value is specified.
从以上说明可以看出,
var a map[string]string = map[string]string{"name":"Jack"})
这也是官方文档中关于make的说明,slice,map,channel使用前,必须先通过make的初始化
Back to allocation. The built-in function make(T, args) serves a
purpose different from new(T). It creates slices, maps, and channels
only, and it returns an initialized (not zeroed) value of type T (not
*T). The reason for the distinction is that these three types represent, under the covers, references to data structures that must
be initialized before use. A slice, for example, is a three-item
descriptor containing a pointer to the data (inside an array), the
length, and the capacity, and until those items are initialized, the
slice is nil. For slices, maps, and channels, make initializes the
internal data structure and prepares the value for use. For instance,make([]int, 10, 100) allocates an array of 100 ints and then creates a
slice structure with length 10 and a capacity of 100 pointing at the
first 10 elements of the array. (When making a slice, the capacity can
be omitted; see the section on slices for more information.) In
contrast, new([]int) returns a pointer to a newly allocated, zeroed
slice structure, that is, a pointer to a nil slice value.
另外,推荐一篇关于zero value ,nil, empty struct的区别和使用说明
https://juejin.cn/post/6895231755091968013