GO 结构体使用 | 青训营笔记

120 阅读5分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天 今天介绍一下结构体简单的使用。

什么是结构体?

结构是表示字段集合的用户定义类型。它可以用于将数据分组到单个单元中而不是将它们中的每一个作为单独的值有意义的地方。

例如,员工有名字、姓氏和年龄。将这三个属性分组到一个名为 Employee 的单个结构中是有意义的.

声明结构

type Employee struct {  
    firstName string
    lastName  string
    age       int
}

上面的代码片段声明了一个结构类型Employee,其中包含firstNamelastNameage。上述 Employee 结构称为命名结构,因为它创建了一个名为 Employee 的新数据类型,使用该数据类型可以创建 Employee Employee 结构Employee

还可以通过在一行中声明属于同一类型的字段后跟类型名称来使此结构更加紧凑。在上面的结构中,firstName 和 lastName 属于同一类型的string,因此结构可以重写为

type Employee struct {  
    firstName, lastName string
    age                 int
}

尽管上述语法节省了几行代码,但它并没有使字段声明显式。请不要使用上述语法。

创建命名结构

让我们使用以下简单程序声明一个命名结构 Employee

package main

import (  
    "fmt"
)

type Employee struct {  
    firstName string
    lastName  string
    age       int
    salary    int
}

func main() {

    //creating struct specifying field names
    emp1 := Employee{
        firstName: "Sam",
        age:       25,
        salary:    500,
        lastName:  "Anderson",
    }

    //creating struct without specifying field names
    emp2 := Employee{"Thomas", "Paul", 29, 800}

    fmt.Println("Employee 1", emp1)
    fmt.Println("Employee 2", emp2)
}

在上述程序的第 7 行中,我们创建了一个命名结构类型 Employee。在上述程序的第 17 行中,emp1 结构是通过指定每个字段名称的值来定义的。声明结构类型时,字段的顺序不一定与字段名称的顺序相同。在这种情况下。我们更改了lastName的位置并将其移至末尾。这将毫无问题地工作。

在上述程序的第 25 行中,emp2 是通过省略字段名称来定义的。在这种情况下,必须保持字段的顺序与结构声明中指定的顺序相同。请不要使用此语法,因为它很难确定哪个值用于哪个字段。 我们在这里指定此格式只是为了了解这也是一个有效的语法:)

上面的程序打印

Employee 1 {Sam Anderson 25 500}  
Employee 2 {Thomas Paul 29 800}  

创建匿名结构

可以在不创建新数据类型的情况下声明结构。这些类型的结构称为匿名结构.

package main

import (  
    "fmt"
)

func main() {  
    emp3 := struct {
        firstName string
        lastName  string
        age       int
        salary    int
    }{
        firstName: "Andreah",
        lastName:  "Nikola",
        age:       31,
        salary:    5000,
    }

    fmt.Println("Employee 3", emp3)
}

在第 8 行。在上述程序中,定义了一个匿名结构变量 emp3。正如我们已经提到的,这个结构被称为匿名,因为它只创建一个新的结构变量emp3,并且没有定义任何新的结构类型,如命名结构。

该程序输出,

Employee 3 {Andreah Nikola 31 5000}  

访问结构的各个字段

点 . 运算符用于访问结构的各个字段。

package main

import (  
    "fmt"
)

type Employee struct {  
    firstName string
    lastName  string
    age       int
    salary    int
}

func main() {  
    emp6 := Employee{
        firstName: "Sam",
        lastName:  "Anderson",
        age:       55,
        salary:    6000,
    }
    fmt.Println("First Name:", emp6.firstName)
    fmt.Println("Last Name:", emp6.lastName)
    fmt.Println("Age:", emp6.age)
    fmt.Printf("Salary: $%d\n", emp6.salary)
    emp6.salary = 6500
    fmt.Printf("New Salary: $%d", emp6.salary)
}

上述程序中的emp6.firstName访问emp6结构体的firstName字段。firstName在第 25 行中,我们修改了员工的工资。该程序打印,

First Name: Sam  
Last Name: Anderson  
Age: 55  
Salary: $6000  
New Salary: $6500  

结构的零值

当定义结构并且未使用任何值显式初始化时,默认情况下为结构的字段分配零值。

package main

import (  
    "fmt"
)

type Employee struct {  
    firstName string
    lastName  string
    age       int
    salary    int
}

func main() {  
    var emp4 Employee //zero valued struct
    fmt.Println("First Name:", emp4.firstName)
    fmt.Println("Last Name:", emp4.lastName)
    fmt.Println("Age:", emp4.age)
    fmt.Println("Salary:", emp4.salary)
}

上面的程序定义了 emp4,但它没有用任何值初始化。因此,firstName 和 lastName 被分配为字符串的零值,即空字符串 ""agesalary被分配为 int 的零值,即 0。该程序打印,

First Name:  
Last Name:  
Age: 0  
Salary: 0  

也可以为某些字段指定值并忽略其余字段。在这种情况下,忽略的字段被分配为零值。

package main

import (  
    "fmt"
)

type Employee struct {  
    firstName string
    lastName  string
    age       int
    salary    int
}

func main() {  
    emp5 := Employee{
        firstName: "John",
        lastName:  "Paul",
    }
    fmt.Println("First Name:", emp5.firstName)
    fmt.Println("Last Name:", emp5.lastName)
    fmt.Println("Age:", emp5.age)
    fmt.Println("Salary:", emp5.salary)
}

在上面的程序中排队。没有16和17,firstNamelastName被初始化,而agesalary不是。因此,agesalary被赋予了零值。该程序输出,

First Name: John  
Last Name: Paul  
Age: 0  
Salary: 0  

指向结构的指针

也可以创建指向结构的指针。

package main

import (  
    "fmt"
)

type Employee struct {  
    firstName string
    lastName  string
    age       int
    salary    int
}

func main() {  
    emp8 := &Employee{
        firstName: "Sam",
        lastName:  "Anderson",
        age:       55,
        salary:    6000,
    }
    fmt.Println("First Name:", (*emp8).firstName)
    fmt.Println("Age:", (*emp8).age)
}

上述程序中的 emp8 是指向 Employee 结构体的指针。(*emp8).firstName 是访问 emp8 结构体的 firstName 字段的语法。该程序打印,

First Name: Sam  
Age: 55  

Go 语言为我们提供了使用 emp8.firstName 而不是显式取消引用 (*emp8).firstNamefirstName 来访问 emp8.firstName 字段的选项。firstName

package main

import (  
    "fmt"
)

type Employee struct {  
    firstName string
    lastName  string
    age       int
    salary    int
}

func main() {  
    emp8 := &Employee{
        firstName: "Sam",
        lastName:  "Anderson",
        age:       55,
        salary:    6000,
    }
    fmt.Println("First Name:", emp8.firstName)
    fmt.Println("Age:", emp8.age)
}

我们使用 emp8.firstName 访问上述程序中的 firstName 字段,该程序还输出,

First Name: Sam  
Age: 55  

以上介绍了 Go 结构体的一些简单使用。