違い: 1. Make は、slice、map、chan タイプのデータの割り当てと初期化にのみ使用できますが、new は任意のタイプのデータを割り当てることができます。 2. 新しい割り当ては型「*Type」であるポインタを返しますが、make は参照である Type を返します。 3. new によって割り当てられたスペースはクリアされ、make によってスペースが割り当てられた後、初期化されます。
このチュートリアルの動作環境: Windows 7 システム、GO バージョン 1.18、Dell G3 コンピューター。
new と make は、Go 言語のメモリ割り当てのプリミティブです。簡単に言うと、new はメモリを割り当てるだけであり、make はスライス、マップ、チャネルの初期化に使用されます。
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 }
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 から 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) //{}
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 }
func make(t Type, size ...IntegerType) Type
です。2 番目のパラメーターは可変長パラメーターであり、スライスの場合、cap と length を指定する必要があり (cap は容量を表し、length は長さ、つまり使用できるサイズを表します)、cap は length より大きい必要があります。ここではキャップとスライスの長さについてはあまり紹介しません。今家があることがわかります。この家はラフな家です。すべての部屋が 3 部屋 (キャップ) で、 1部屋(長さ)。
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 } }
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 は任意のタイプのデータを割り当てることができます。プログラミング教育 ]
以上がGo言語のmakeとnewの違いは何ですかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。