Golang basics struct和new()关键字

时间:2015-12-31 08:27:47

标签: pointers struct go

我正在学习golang,当我阅读描述Structures的章节时,我遇到了不同的方法来初始化结构。

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 }

请帮助我解决疑惑。

    在使用pointerp1 := &p3
  1. pointerp1p3的引用变量,它保存实际数据。同样,保存pointerp2的数据的实际变量是什么?

  2. 使用这些不同类型的初始化的最佳方案是什么?

3 个答案:

答案 0 :(得分:37)

new为新项目分配归零存储或输入任何内容,然后返回指向它的指针。我认为,如果你使用new vs短变量声明:= type{},它实际上只是偏好

对于pointer2pointer2变量保存自己的数据

// initializing a zeroed 'passport in memory'
pointerp2 := new(passport)
// setting the field Name to whatever
pointerp2.Name = "Anotherscott"

new在内存中分配归零存储并返回指向它的指针,所以简而言之,new会返回指向你正在做的任何内容的指针,这就是为什么pointerp2返回&{ Anotherscott } < / p>

当你传递一个你需要修改的变量时,你主要想要使用指针(但要注意数据竞争使用互斥或​​通道如果你需要读取和写入来自不同函数的变量)

人们使用的常用方法而不是new只是短指针类型:

blah := &passport{}

blah现在是指向护照

的指针

你可以在这个游乐场看到:

http://play.golang.org/p/9OuM2Kqncq

传递指针时,可以修改原始值。传递非指针时,无法修改它。那是因为go变量作为副本传递。因此,在iDontTakeAPointer函数中,它接收到测试器结构的副本,然后修改名称字段然后返回,这对我们没有任何作用,因为它正在修改副本而不是原始副本。

答案 1 :(得分:3)

  1. 还有保存数据的变量。您可以使用*pointerp2取消引用指针,甚至将其指定给变量(p2 := pointerp2),但此变量将是数据的副本。也就是说,修改一个不再影响另一个(http://play.golang.org/p/9yRYbyvG8q)。

  2. new往往不那么受欢迎,特别是在结构方面。可以在https://softwareengineering.stackexchange.com/a/216582找到关于其目的(提示:它首先出现)和用例的良好讨论。

  3. 编辑:此外,p1实际上并不是p3的另一种初始化,而是将值分配给任何类型的字段,而不是将它们初始化为零值({{1 } ""string代表nil)。任何省略的字段都会发生同样的情况:

    []byte

    在这种情况下,p4 := passport{ Name: "Scott", Surname: "Adam", } p4.Photo仍然是零值(分别为p4.DateOfBirthnil)。 ""只是一个省略所有字段的情况。

答案 2 :(得分:2)

所有新关键字的作用基本上都是创建所需类型的实例。但是,它不是返回该类型的普通声明,而是引用它并在程序进程堆中返回该类型的实际内存地址。