Pointers Golang basics结构和new()关键字
我在学习golang,在学习描述结构的章节时,我遇到了初始化结构的不同方法Pointers Golang basics结构和new()关键字,pointers,struct,go,Pointers,Struct,Go,我在学习golang,在学习描述结构的章节时,我遇到了初始化结构的不同方法 p1 := passport{} var p2 passport p3 := passport{ Photo: make([]byte, 0, 0), Name: "Scott", Surname: "Adam", DateOfBirth: "Some time", } fmt.Printf("%s\n%s\n%s\n", p1, p2, p3) 而这些将结构的值打印为 {} {
p1 := passport{}
var p2 passport
p3 := passport{
Photo: make([]byte, 0, 0),
Name: "Scott",
Surname: "Adam",
DateOfBirth: "Some time",
}
fmt.Printf("%s\n%s\n%s\n", p1, p2, p3)
而这些将结构的值打印为
{}
{ }
{Scott Adam某时}
,下面的代码使用符号AND打印,因为它是一个参考
pointerp1 := &p3
fmt.Printf("%s", pointerp1)
pointerp2 := new(passport)
pointerp2.Name = "Anotherscott"
fmt.Printf("%s", pointerp2)
&{Scott Adam某时}&{Anotherscott}
请帮我解答我的疑问
pointerp1:=&p3
中,pointerp1
是p3
的参考变量,它保存实际数据。类似地,保存pointerp2
数据的实际变量是什么new
为新项目或类型分配零存储,然后返回指向该项目或类型的指针。我认为如果您使用new
vs短变量声明:=type{}
,这实际上并不重要,它主要只是首选项
对于pointer2
,执行此操作时,pointer2
变量保存自己的数据
// initializing a zeroed 'passport in memory'
pointerp2 := new(passport)
// setting the field Name to whatever
pointerp2.Name = "Anotherscott"
new
在内存中分配归零存储并返回指向该存储的指针,因此简而言之,new将返回指向您正在进行的任何操作的指针,这就是为什么pointerp2
返回&{Anotherscott}
在传递需要修改的变量时,您主要希望使用指针(但如果需要从不同的函数读取和写入变量,请小心使用互斥量或通道)
人们使用的一种代替新的的常用方法是指针类型:
blah:=&passport{}
blah现在是指向passport类型的指针
你可以在这个操场上看到:
传递指针时,可以修改原始值。传递非指针时,不能修改它。这是因为in-go变量作为副本传递。因此,在iDontTakeAPointer
函数中,它接收tester结构的副本,然后修改名称字段,然后返回,这对我们没有任何作用,因为它修改的是副本而不是原件
还有一个变量保存数据。您可以使用*pointerp2
取消对指针的引用,甚至将其分配给变量(p2:=pointerp2
),但该变量将是数据的副本。也就是说,修改一个不再影响另一个()
new
不太受欢迎,尤其是在结构方面。关于它的用途(提示:它首先出现)和用例的详细讨论可以在上找到
编辑:另外,p1
与p3
实际上并不是一种不同的初始化类型,而是将它们初始化为零值(“
用于字符串
,nil
用于[]字节
)。任何省略的字段也会发生同样的情况:
p4 := passport{
Name: "Scott",
Surname: "Adam",
}
在这种情况下,p4.Photo
和p4.DateOfBirth
仍然是零值(nil
和”
)。passport{}
案例只是一个省略所有字段的案例。新关键字所做的一切基本上就是创建所需类型的实例。但是,它不是返回类型的普通声明,而是引用它并在程序进程堆中返回该类型的实际内存地址 @Datsik它打印[]
,但其值nil
;看见这里也有很好的讨论。TL;DR:nil切片在许多方面都像空切片。我知道这一点,但对于下一个新的广告来说,这应该理解,即使他们看到[]它实际上仍然是零。一个典型的例子是json值为null:即使在调试时,您认为您有一个空的切片,但Go并没有“引用”的概念。不要将指针命名为“引用”。iDoTakeAPointer
函数也会收到指针的副本(但它指向的数据完全相同)。我发现go团队做出了一个非常奇怪的决定,&
是其他语言使用的,new
似乎您正在分配内存并将项目复制到内存中,而这恰恰相反。