golang make와 new의 차이점에 대한 자세한 설명

  목차

하나, 새로운

둘, make

셋, 새로운 것과 만드는 것의 차이


많은 친구들이 Golang을 처음 접했을 때 메모리를 할당하는 두 가지 기능이있는 이유를 이해하지 못했습니다 : new와 make. 속담처럼 : 존재는 합리적입니다. 둘의 차이점에 대해 자세히 설명하겠습니다. 

하나, 새로운

먼저 함수 선언을 살펴보십시오.

func new(Type) *Type

new는 메모리를 할당하는 데 사용되는 Golang의 내장 함수입니다. 첫 번째 매개 변수는 유형이고 반환 값은 유형의 포인터입니다. 값은 "0"(유형에 해당하는 0 값, int는 0으로 초기화되고 bool은 false로 초기화됩니다.)

예 :

package main
import "fmt"

func main() {
	id := new(int)
	name := new(string)
	flag := new(bool)
	fmt.Printf("id type: %T  value: %v\n", id, *id)
	fmt.Printf("name type: %T  value: %v\n", name, *name)
	fmt.Printf("flag type: %T  value: %v\n", flag, *flag)
}

산출:

id type: *int  value: 0
name type: *string  value: 
flag type: *bool  value: false

위 예제에서 알 수 있듯이 초기화 된 "zero"값은 타입에 따라 다르며 정수는 0으로 초기화되고 문자열은 빈으로 초기화되며 bool 타입은 false로 초기화됩니다. 

둘, make

먼저 함수 선언을 살펴보십시오. 

func make(t Type, size ...IntegerType) Type

make는 Golang의 내장 함수로 객체의 슬라이스, 맵, 채널 유형 할당 하고 초기화하는 데만 사용되며 세 유형 모두 구조입니다. 반환 값은 포인터가 아닌 형식입니다.

슬라이스 소스 코드 구조 :

type slice struct {
    array unsafe.Pointer  //指针
    len   int             //长度
    cap   int             //容量
}

맵 소스 코드 구조 :

// A header for a Go map.
type hmap struct {
	// Note: the format of the hmap is also encoded in cmd/compile/internal/gc/reflect.go.
	// Make sure this stays in sync with the compiler's definition.
	count     int // # live cells == size of map.  Must be first (used by len() builtin)
	flags     uint8
	B         uint8  // log_2 of # of buckets (can hold up to loadFactor * 2^B items)
	noverflow uint16 // approximate number of overflow buckets; see incrnoverflow for details
	hash0     uint32 // hash seed

	buckets    unsafe.Pointer // array of 2^B Buckets. may be nil if count==0.
	oldbuckets unsafe.Pointer // previous bucket array of half the size, non-nil only when growing
	nevacuate  uintptr        // progress counter for evacuation (buckets less than this have been evacuated)

	extra *mapextra // optional fields
}

채널 소스 구조 :

type hchan struct {
	qcount   uint           // total data in the queue
	dataqsiz uint           // size of the circular queue
	buf      unsafe.Pointer // points to an array of dataqsiz elements
	elemsize uint16
	closed   uint32
	elemtype *_type // element type
	sendx    uint   // send index
	recvx    uint   // receive index
	recvq    waitq  // list of recv waiters
	sendq    waitq  // list of send waiters

	// lock protects all fields in hchan, as well as several
	// fields in sudogs blocked on this channel.
	//
	// Do not change another G's status while holding this lock
	// (in particular, do not ready a G), as this can deadlock
	// with stack shrinking.
	lock mutex
}

 예 :

package main

import "fmt"

func main() {
	//map
	fmt.Println("map:")
	var nameId = make(map[string]int, 0)
	fmt.Printf("nameId \ntype: %#v\n", nameId)
	nameId["Golang"] = 1
	nameId["C++"] = 2
	nameId["PHP"] = 3

	for name, id := range nameId {
		fmt.Printf("name = %v, id = %v\n", name, id)
	}
	// slice
	var hobby = make([]string, 2, 100) // 其中 2是长度,100是容量
	hobby[0] = "打篮球"
	hobby[1] = "乒乓球"
	fmt.Println("\nslice:")
	fmt.Printf("length = %v  caps = %v\n", len(hobby), cap(hobby))
	for _, name := range hobby {
		fmt.Println(name)
	}
	// channel
	ch := make(chan int, 3)
	ch <- 1
	ch <- 2
	ch <- 8
	close(ch)
	fmt.Println("\nchannel:")
	for val := range ch { // 遍历数据
		fmt.Println(val)
	}
}

산출:

[root@localhost test]# go run main.go 
map:
nameId 
type: map[string]int{}
name = Golang, id = 1
name = C++, id = 2
name = PHP, id = 3

slice:
length = 2  caps = 100
打篮球
乒乓球

channel:
1
2
8
[root@localhost test]#

셋, 새로운 것과 만드는 것의 차이

1. new와 make는 모두 메모리 할당에 사용됩니다.

2. 모두 new 및 make 메모리를 힙에 할당합니다.

3. New는 포인터 유형에 대한 메모리를 할당하고 반환 값은 할당 유형의 포인터이며 New는 슬라이스, 맵 및 채널에 대한 메모리를 직접 할당 할 수 없습니다.

4. Make는 슬라이스, 맵 및 채널의 초기화에만 사용되며 반환 값은 포인터가 아닌 유형 자체입니다.

 

추천

출처blog.csdn.net/u011074149/article/details/111567784