目次
make は、chan、map、slice の 3 種類のコンテンツ割り当てを作成するために特別に使用され、それらを初期化できます。これら 3 つのデータ型自体が参照型であるため、make の戻り値の型は引数へのポインターではなく、引数と同じ型です。 " >makemake は、chan、map、slice の 3 種類のコンテンツ割り当てを作成するために特別に使用され、それらを初期化できます。これら 3 つのデータ型自体が参照型であるため、make の戻り値の型は引数へのポインターではなく、引数と同じ型です。
ホームページ バックエンド開発 Golang Go言語のmakeとnewの違いは何ですか

Go言語のmakeとnewの違いは何ですか

Jan 09, 2023 am 11:44 AM
golang 言語を移動 make new

違い: 1. Make は、slice、map、chan タイプのデータの割り当てと初期化にのみ使用できますが、new は任意のタイプのデータを割り当てることができます。 2. 新しい割り当ては型「*Type」であるポインタを返しますが、make は参照である Type を返します。 3. new によって割り当てられたスペースはクリアされ、make によってスペースが割り当てられた後、初期化されます。

Go言語のmakeとnewの違いは何ですか

このチュートリアルの動作環境: Windows 7 システム、GO バージョン 1.18、Dell G3 コンピューター。

new と make は、Go 言語のメモリ割り当てのプリミティブです。簡単に言うと、new はメモリを割り当てるだけであり、make はスライス、マップ、チャネルの初期化に使用されます。

#new

new(T) 関数はメモリを割り当てる組み込み関数で、型ごとにメモリを割り当て、値をゼロに初期化し、そのメモリアドレスを返します。

構文は

func new(Type) *Type

ご存知のとおり、既存の変数をそのポインターに割り当てることができます。

var p int
var v *int
v = &p
*v = 11
fmt.Println(*v)
ログイン後にコピー

では、まだ変数ではない場合はどうすればよいでしょうか?直接割り当ててもらえますか?

func main() {
	var v *int
	*v = 8
	fmt.Println(*v)

	// panic: runtime error: invalid memory address or nil pointer dereference
	// [signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x47df36]

	// goroutine 1 [running]:
	// main.main()
	// 	/tmp/sandbox1410772957/prog.go:9 +0x16
}
ログイン後にコピー

エラー結果はコード内のコメントに示されているとおりです。 ######の解き方?これは、Go が新しい初期化アドレスを提供することで解決できます。

func main() {
	var v *int
	// v 是一个 int 类型的指针,v 的地址和 v 的值  0xc0000ba018 <nil>
	fmt.Println("v 是一个 int 类型的指针,v 的地址和 v 的值 ", &v, v)   
	// 分配给 v 一个指向的变量             
	v = new(int)    
	// v 是一个 int 类型的指针,v 的地址和 v 的值  0xc0000ba018 0xc000018030 0,此时已经分配给了 v 指针一个指向的变量,但是变量为零值                                                  
	fmt.Println("v 是一个 int 类型的指针,v 的地址, v 的值和 v 指向的变量的值 ", &v, v, *v) 
	*v = 8
	// v 是一个 int 类型的指针,v 的地址和 v 的值  0xc0000ba018 0xc000018030 8,此时又像这个变量中装填了一个值 8
	fmt.Println("v 是一个 int 类型的指针,v 的地址, v 的值和 v 指向的变量的值 ", &v, v, *v) 
	
	// 整个过程可以理解为给 v 指针指向了一个匿名变量
}
ログイン後にコピー

ポインタ変数を nil の値で初期化することは、直接の代入ではないことがわかります。値 0xc000018030 から Go言語のmakeとnewの違いは何ですかnew までのポインタを返します。

は新しく割り当てられた int 型を指し、ゼロ値はその値です。

さらに、ゼロ値はポインター型によって異なることに注意することが重要です。詳細については、この記事

を参照してください。または、以下のコードを参照することもできます。

type Name struct {
    P string
}
var av *[5]int
var iv *int
var sv *string
var tv *Name

av = new([5]int)
fmt.Println(*av) //[0 0 0 0 0 0]
iv = new(int)
fmt.Println(*iv) // 0
sv = new(string) 
fmt.Println(*sv) //
tv = new(Name)
fmt.Println(*tv) //{}
ログイン後にコピー
上記は通常の型new()の処理後に値を代入する方法ですが、ここでは複合型(配列、構造体)の処理後に値を代入する方法を説明します。しかしここで、元の記事の著者は間違っていると思います。スライス、マップ、チャネルの場合、new は

配列インスタンス

func main() {
	// 声明一个数组指针
	var a *[5]int
	fmt.Printf("a: %p %#v \n", &a, a) //a: 0xc04200a180 [5]int{0, 0, 0, 0, 0}
	// 分配一个内存地址给 a(数组指针)指向
	a = new([5]int)
	fmt.Printf("a: %p %#v \n", &a, a) //av: 0xc000074018 &[5]int{0, 0, 0, 0, 0}
	// 修改这个数组中的值
	(*a)[1] = 8
	fmt.Printf("a: %p %#v \n", &a, a) //av: 0xc000006028 &[5]int{0, 8, 0, 0, 0}
}
ログイン後にコピー

構造インスタンス

type mystruct struct {
	name string
	age  int
}

func main() {
	var people *mystruct
	people = new(mystruct)
	people.name = "zhangsan"
	people.age = 11

	fmt.Printf("%v, %v", people.name, people.age) // zhangsan, 11
}
ログイン後にコピー

しか開けないからです。

makemake は、chan、map、slice の 3 種類のコンテンツ割り当てを作成するために特別に使用され、それらを初期化できます。これら 3 つのデータ型自体が参照型であるため、make の戻り値の型は引数へのポインターではなく、引数と同じ型です。

構文は:

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

です。2 番目のパラメーターは可変長パラメーターであり、スライスの場合、cap と length を指定する必要があり (cap は容量を表し、length は長さ、つまり使用できるサイズを表します)、cap は length より大きい必要があります。

ここではキャップとスライスの長さについてはあまり紹介しません。今家があることがわかります。この家はラフな家です。すべての部屋が 3 部屋 (キャップ) で、 1部屋(長さ)。

これら 3 つのタイプにメモリを割り当てるために new を使用しないのはなぜでしょうか?実験をしてみましょう。

func main() {
	var s *[]int
	fmt.Printf("s 的地址是: %p, s 的值是 %p\n", &s, s) // s 的地址是: 0xc00000e028, s 的值是 0x0
	s = new([]int)
	fmt.Printf("s 的地址是: %p, s 的值是 %p\n", &s, s) // s 的地址是: 0xc00000e028, s 的值是 0xc00011a018
	(*s)[0] = 1
	fmt.Println("s 的地址是: %p, s 的值是 %p\n", &s, s) // panic: runtime error: index out of range [0] with length 0
}
}
ログイン後にコピー

スライスに値を代入すると長さが0になっていることがわかりますが、具体的な理由については、それを知っている友達がコメント欄にメッセージを残してくれると思います。

したがって、多くの場合、これら 3 種類の作成を実行するには make を使用することが推奨されます。

スライス インスタンス

func main() {
	// 第一个 size 是 length,第二个 size 是 cap
	a := make([]int, 5, 10)
	// a: 0xc00011a018 []int{0, 0, 0, 0, 0},cap: 10, length: 5 
	fmt.Printf("a: %p %#v,cap: %d, length: %d \n", &a, a, cap(a), len(a)) 
}
ログイン後にコピー

マップ インスタンス

func main() {
	// 第一个 string 是 key,第二个 string 是 value
	mapInstance := make(map[string]string, 5)
	mapInstance["第一名"] = "张三"
	mapInstance["第二名"] = "李四"
	mapInstance["第三名"] = "王五"

	fmt.Println(mapInstance) // map[第一名:张三 第三名:王五 第二名:李四]
}
ログイン後にコピー

チャネル インスタンス

func countNum(temp int, ch chan int) {
	i := temp + 1
	ch <- i
	fmt.Println("已经将 i 发往通道 c 中")
}

func main() {
	ch := make(chan int)
	go countNum(1, ch)
	res := <-ch
	fmt.Println("已经从 ch 中获取 i 并保存在 res 中")
	fmt.Println("res 是", res)
}
ログイン後にコピー

概要:

make 関数はマップ、スライス、チャネルにのみ使用され、ポインターを返しません。明示的なポインタを取得したい場合は、新しい関数を使用して割り当てるか、変数のアドレスを明示的に使用します。

Go 言語における new と make の主な違いは次のとおりです。

make は、slice、map、および chan 型のデータの割り当てと初期化にのみ使用できます。 ; new は任意のタイプのデータを割り当てることができます。
  • 新しい割り当ては、*Type 型であるポインタを返します。make は、Type である参照を返します。
  • new によって割り当てられたスペースはクリアされ、make によってスペースが割り当てられた後、初期化されます。
  • [関連する推奨事項:
  • Go ビデオ チュートリアル

プログラミング教育 ]

以上がGo言語のmakeとnewの違いは何ですかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

GOの浮動小数点番号操作に使用されるライブラリは何ですか? GOの浮動小数点番号操作に使用されるライブラリは何ですか? Apr 02, 2025 pm 02:06 PM

GO言語の浮動小数点数操作に使用されるライブラリは、精度を確保する方法を紹介します...

Go's Crawler Collyのキュースレッドの問題は何ですか? Go's Crawler Collyのキュースレッドの問題は何ですか? Apr 02, 2025 pm 02:09 PM

Go Crawler Collyのキュースレッドの問題は、Go言語でColly Crawler Libraryを使用する問題を調査します。 �...

GO言語の「VAR」と「タイプ」キーワード定義構造の違いは何ですか? GO言語の「VAR」と「タイプ」キーワード定義構造の違いは何ですか? Apr 02, 2025 pm 12:57 PM

GO言語で構造を定義する2つの方法:VARとタイプのキーワードの違い。構造を定義するとき、GO言語はしばしば2つの異なる執筆方法を見ます:最初...

GOのどのライブラリが大企業によって開発されていますか、それとも有名なオープンソースプロジェクトによって提供されていますか? GOのどのライブラリが大企業によって開発されていますか、それとも有名なオープンソースプロジェクトによって提供されていますか? Apr 02, 2025 pm 04:12 PM

大企業または有名なオープンソースプロジェクトによって開発されたGOのどのライブラリが開発されていますか? GOでプログラミングするとき、開発者はしばしばいくつかの一般的なニーズに遭遇します...

Goでは、Printlnとstring()関数を備えた文字列を印刷すると、なぜ異なる効果があるのですか? Goでは、Printlnとstring()関数を備えた文字列を印刷すると、なぜ異なる効果があるのですか? Apr 02, 2025 pm 02:03 PM

Go言語での文字列印刷の違い:printlnとstring()関数を使用する効果の違いはGOにあります...

Redisストリームを使用してGO言語でメッセージキューを実装する場合、user_idタイプの変換の問題を解決する方法は? Redisストリームを使用してGO言語でメッセージキューを実装する場合、user_idタイプの変換の問題を解決する方法は? Apr 02, 2025 pm 04:54 PM

redisstreamを使用してGo言語でメッセージキューを実装する問題は、GO言語とRedisを使用することです...

Golandのカスタム構造ラベルが表示されない場合はどうすればよいですか? Golandのカスタム構造ラベルが表示されない場合はどうすればよいですか? Apr 02, 2025 pm 05:09 PM

Golandのカスタム構造ラベルが表示されない場合はどうすればよいですか?ゴーランドを使用するためにGolandを使用する場合、多くの開発者はカスタム構造タグに遭遇します...

Golang Generic Function Typeの制約がVSCodeで自動的に削除されるという問題を解決する方法は? Golang Generic Function Typeの制約がVSCodeで自動的に削除されるという問題を解決する方法は? Apr 02, 2025 pm 02:15 PM

VSCODEユーザーのGolang Generic Function Typeの制約の自動削除は、VSCODEを使用してGolangコードを書くときに奇妙な問題に遭遇する可能性があります。いつ...

See all articles