V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
hzjseasea
V2EX  ›  Go 编程语言

关于 Golang 中 make 函数的疑惑

  •  
  •   hzjseasea · 2022-04-11 17:42:07 +08:00 · 1586 次点击
    这是一个创建于 717 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Go 里面 make 返回的是 和传入参数的同类型的实例(Type) 还是传入参数同类型的指针(*Type)

    https://go.dev/doc/effective_go#allocation_make , 官方的文档里面有写道

    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)

    源码里面也有写到 /usr/local/opt/go/libexec/src/builtin/builtin.go

    // 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, size ...IntegerType) Type
    

    那说明返回的内容就是一个和传入参数同类型的实例

    然后在 /usr/local/opt/go/libexec/src/runtime/map.go runtime 包里面的 makemap 函数返回的是一个*T 的内容

    // makemap implements Go map creation for make(map[k]v, hint).
    // If the compiler has determined that the map or the first bucket
    // can be created on the stack, h and/or bucket may be non-nil.
    // If h != nil, the map can be created directly in h.
    // If h.buckets != nil, bucket pointed to can be used as the first bucket.
    func makemap(t *maptype, hint int, h *hmap) *hmap {
    	mem, overflow := math.MulUintptr(uintptr(hint), t.bucket.size)
    	if overflow || mem > maxAlloc {
    		hint = 0
    	}
    
    	// initialize Hmap
    	if h == nil {
    		h = new(hmap)
    	}
    	h.hash0 = fastrand()
    
    	// Find the size parameter B which will hold the requested # of elements.
    	// For hint < 0 overLoadFactor returns false since hint < bucketCnt.
    	B := uint8(0)
    	for overLoadFactor(hint, B) {
    		B++
    	}
    	h.B = B
    
    	// allocate initial hash table
    	// if B == 0, the buckets field is allocated lazily later (in mapassign)
    	// If hint is large zeroing this memory could take a while.
    	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
    }
    

    有无大佬帮忙解释一下

    8 条回复    2022-06-01 14:01:40 +08:00
    pigmen
        1
    pigmen  
       2022-04-11 17:58:38 +08:00
    map := *hmap

    可以这么理解
    labulaka521
        3
    labulaka521  
       2022-04-11 22:35:21 +08:00 via iPhone
    我觉得 make 返回的不是指针,但返回的类型底层实现是一个指针
    hzjseasea
        4
    hzjseasea  
    OP
       2022-04-12 10:01:01 +08:00
    @labulaka521 源码里面返回的是一个指针, 然后编译期的源码在这个下面 /usr/local/opt/go/libexec/src/cmd/compile/internal/gc/builtin/runtime.go
    ```
    func makemap(mapType *byte, hint int, mapbuf *any) (hmap map[any]any)
    ```
    返回的不是一个指针
    tairan2006
        5
    tairan2006  
       2022-04-12 10:18:51 +08:00
    labulaka521
        6
    labulaka521  
       2022-04-12 12:19:11 +08:00
    @hzjseasea slice 和 map 还不太一致 我看了下确实是指向一个 hmap 的指针
    hzjseasea
        7
    hzjseasea  
    OP
       2022-04-12 14:34:22 +08:00
    fy1206
        8
    fy1206  
       2022-06-01 14:01:40 +08:00
    楼主 给个联系方式 交流一下
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3188 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 14:24 · PVG 22:24 · LAX 07:24 · JFK 10:24
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.