왜 내가 () 또는 new ()를 만들 것입니까?
도입 문서 사이의 차이를 설명하는 많은 단락을 할애 new()
하고 make()
있지만, 실제로는, 당신은 지역의 범위 내에서 객체를 생성하고 반환 할 수 있습니다.
할당 자 쌍을 왜 사용 하시겠습니까?
당신이 할 수있는 것들 make
다른 방법으로는 할 수 없습니다 :
- 채널 만들기
- 공간이 미리 할당 된 맵 만들기
- 공간이 미리 할당되거나 len! = cap로 슬라이스를 만듭니다.
정당화하기가 조금 더 어렵습니다 new
. 가장 쉬운 것은 비 복합 유형에 대한 포인터를 만드는 것입니다. 아래의 두 기능은 동일합니다. 하나는 조금 더 간결합니다.
func newInt1() *int { return new(int) }
func newInt2() *int {
var i int
return &i
}
Go에는 여러 가지 메모리 할당 및 값 초기화 방법이 있습니다.
&T{...}
, &someLocalVar
, new
,make
복합 리터럴을 만들 때 할당이 발생할 수도 있습니다.
new
정수와 같은 값을 할당하는 데 사용할 수 있습니다 &int
.
new(Point)
&Point{} // OK
&Point{2, 3} // Combines allocation and initialization
new(int)
&int // Illegal
// Works, but it is less convenient to write than new(int)
var i int
&i
의 차이 new
와는 make
다음의 예를 보면 알 수있다 :
p := new(chan int) // p has type: *chan int
c := make(chan int) // c has type: chan int
Go에 new
and make
가 없지만 내장 기능 이 있다고 가정합니다 NEW
. 그런 다음 예제 코드는 다음과 같습니다.
p := NEW(*chan int) // * is mandatory
c := NEW(chan int)
는 *
필수가 될 것입니다 그래서 :
new(int) --> NEW(*int)
new(Point) --> NEW(*Point)
new(chan int) --> NEW(*chan int)
make([]int, 10) --> NEW([]int, 10)
new(Point) // Illegal
new(int) // Illegal
예, 단일 내장 기능으로 병합 new
및 통합 make
할 수 있습니다. 그러나 하나의 내장 기능이 내장 된 두 기능을 갖는 것보다 새로운 Go 프로그래머에게 더 많은 혼란을 야기 할 가능성이 있습니다.
위의 모든 사항을 고려하면 더 적절 new
하고 make
분리 된 상태로 유지됩니다.
make 함수는 slice, map 또는 chan 유형의 객체 만 할당하고 초기화합니다. new와 마찬가지로 첫 번째 인수는 유형입니다. 그러나 크기에 대한 두 번째 주장이 필요할 수도 있습니다. new와 달리 make의 반환 유형은 포인터의 유형이 아니라 인수의 유형과 동일합니다. 그리고 할당 된 값이 초기화됩니다 (새로운 것과 같이 0으로 설정되지 않음). 그 이유는 slice, map 및 chan이 데이터 구조이기 때문입니다. 초기화해야합니다. 그렇지 않으면 사용할 수 없습니다. 이것이 new ()와 make ()가 달라야하는 이유입니다.
Effective Go의 다음 예는 매우 명확합니다.
p *[]int = new([]int) // *p = nil, which makes p useless
v []int = make([]int, 100) // creates v structure that has pointer to an array, length field, and capacity field. So, v is immediately usable
당신은 필요한 make()
채널과지도를 만들기 위해 (그리고 조각을, 그러나 그 너무 배열을 만들 수 있습니다). 대체 할 방법이 없으므로 make()
사전에서 제거 할 수 없습니다 .
As for new()
, I don't know of any reason offhand why you need it when you can use struct syntax. It does have a unique semantic meaning though, which is "create and return a struct with all fields initialized to their zero value", which can be useful.
Apart from everything explained in Effective Go, The main difference between new(T)
and &T{}
is that the latter explicitly performs a heap allocation. However it should be noted that this is implementation dependent and thus may be subject to change.
Comparing make
to new
makes little sense as the two perform entirely different functions. But this is explained in detail in the linked article.
new(T) : it returns a pointer to type T a value of type *T, it allocates and zeroes the memory. new(T) is equivalent to &T{}.
make(T) : it returns an initialized value of type T, It allocates and initializes the memory. Its used for slices, map and channels.
new(T)
- Allocates memory, and sets it to the zero value for type T..
..that is0
for int,""
for string andnil
for referenced types (slice, map, chan)Note that referenced types are just pointers to some underlying data structures, which won't be created by
new(T)
Example: in case of slice, the underlying array won't be created, thusnew([]int)
returns a pointer to nothingmake(T)
- Allocates memory for referenced data types (slice, map, chan), plus initializes their underlying data structuresExample: in case of slice, the underlying array will be created with the specified length and capacity
Bear in mind that, unlike C, an array is a primitive type in Go!
That being said:
make(T)
behaves like composite-literal syntax new(T)
behaves like var
(when the variable is not initialized) func main() {
fmt.Println("-- MAKE --")
a := make([]int, 0)
aPtr := &a
fmt.Println("pointer == nil :", *aPtr == nil)
fmt.Printf("pointer value: %p\n\n", *aPtr)
fmt.Println("-- COMPOSITE LITERAL --")
b := []int{}
bPtr := &b
fmt.Println("pointer == nil :", *bPtr == nil)
fmt.Printf("pointer value: %p\n\n", *bPtr)
fmt.Println("-- NEW --")
cPtr := new([]int)
fmt.Println("pointer == nil :", *cPtr == nil)
fmt.Printf("pointer value: %p\n\n", *cPtr)
fmt.Println("-- VAR (not initialized) --")
var d []int
dPtr := &d
fmt.Println("pointer == nil :", *dPtr == nil)
fmt.Printf("pointer value: %p\n", *dPtr)
}
Run the program
-- MAKE --
pointer == nil : false
pointer value: 0x118eff0 # address to underlying array
-- COMPOSITE LITERAL --
pointer == nil : false
pointer value: 0x118eff0 # address to underlying array
-- NEW --
pointer == nil : true
pointer value: 0x0
-- VAR (not initialized) --
pointer == nil : true
pointer value: 0x0
Further reading:
https://golang.org/doc/effective_go.html#allocation_new https://golang.org/doc/effective_go.html#allocation_make
참고URL : https://stackoverflow.com/questions/9320862/why-would-i-make-or-new
'IT' 카테고리의 다른 글
AWK 다중 분리 문자 (0) | 2020.05.17 |
---|---|
특정 파일에 대한 Git 병합 전략을 선택하십시오 (“우리”,“광산”,“그들의”) (0) | 2020.05.17 |
왜 GCC는 거의 동일한 C 코드에 대해 이렇게 완전히 다른 어셈블리를 생성합니까? (0) | 2020.05.17 |
Linux에서 Latex 시작하기 (0) | 2020.05.17 |
iOS8에서 [UIScreen mainScreen] .bounds.size가 방향에 따라 달라 집니까? (0) | 2020.05.17 |