我当时正在学习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)
这些函数将结构的值打印为{ } { } { Scott Adam Some time}
,则下面的代码打印时带有一个&号,因为它是一个引用。
pointerp1 := &p3
fmt.Printf("%s", pointerp1)
pointerp2 := new(passport)
pointerp2.Name = "Anotherscott"
fmt.Printf("%s", pointerp2)
&{ Scott Adam Some time}&{ Anotherscott }
请帮助我消除疑虑。
1.在pointerp1 := &p3
的用法中,pointerp1
是p3
的引用变量,它保存实际数据。同样,保存pointerp2
数据的实际变量是什么?
1.使用这些不同类型的初始化的最佳方案是什么?
4条答案
按热度按时间vd2z7a6w1#
new
为一个新项或任何类型分配一个置零的存储空间,然后返回一个指向它的指针。我不认为这真的很重要,如果你使用new
与短变量声明:= type{}
,它主要是首选项对于
pointer2
,pointer2
变量保存自己的数据在内存中分配置零的存储空间,并返回一个指针,简而言之,new将返回一个指针,指向您正在创建的内容,这就是为什么
pointerp2
返回&{ Anotherscott }
当你传递一个你需要修改的变量时,你主要想使用指针(但是要小心数据竞争,如果你需要从不同的函数读取和写入一个变量,使用互斥锁或通道)
人们常用的一个方法是shortdec,它是一个指针类型:
blah := &passport{}
blah现在是passport类型的指针
在这个操场上你可以看到:
http://play.golang.org/p/9OuM2Kqncq
当传递一个指针时,你可以修改原始值。当传递一个非指针时,你不能修改它。这是因为在go中的变量是作为一个副本传递的。所以在
iDontTakeAPointer
函数中,它接收一个tester结构体的副本,然后修改name字段,然后返回,这对我们没有任何作用,因为它修改的是副本而不是原始值。ruoxqz4g2#
1.还有一个变量保存着数据。你可以使用
*pointerp2
来取消指针的引用,甚至可以将它赋给一个变量(p2 := pointerp2
),但是这个变量将是数据的副本。也就是说,修改一个变量不再影响另一个变量(http://play.golang.org/p/9yRYbyvG8q)。new
不太受欢迎,尤其是在结构体方面。它是第一个出现的),并且可以在https://softwareengineering.stackexchange.com/a/216582中找到用例。编辑:同样,
p1
与p3
并不是真正不同的初始化类型,但不是给类型的任何字段赋值,而是将它们初始化为零值(""
对应string
,nil
对应[]byte
)。在这种情况下,
p4.Photo
和p4.DateOfBirth
仍然是零值(分别为nil
和""
),而passport{}
只是省略了所有字段的一种情况。s71maibg3#
new关键字所做的基本上就是创建一个你想要的类型的示例,但是它不是返回类型的普通声明,而是引用它并返回该类型在程序进程堆中的实际内存地址。
8wtpewkr4#
我在golang遇到了一个奇怪的现象,我声明为
myptr:= new(ptrtype)
的指针导致if myptr==nil
为false,所以我继续尝试将其定义为myptr:=&ptrtype{}
,瞧!我完全不知道为什么前面的语法对其他9个指针有效,而我必须对第10个指针这样做(实际上它是调用序列中的第一个)。如果有人遇到这个,并且是围棋Maven,可以解释为什么会这样?据我所知,最初的语法应该求值为nil,但实际上没有。