Go-学会并使用结构体

本节重点:

  • 学会并使用结构体

概念

数组、切片和 Map 可以用来表示同一种数据类型的集合,但是当我们要表示不同数据类型的集合时就需要用到结构体。

结构体是由零个或多个任意类型的值聚合成的实体,它可以用于将数据分组为一个单元而不是将它们中的每一个作为单独的值。

声明一个结构体

Go 里面用关键字 type 和 struct 用来定义结构体,语法如下:

type StructName struct{
    FieldName type
}

我们来定义一个学生结构体:

package main

import "fmt"

type Student struct {
    Age     int
    Name    string
}

func main() {
    stu := Student{
        Age:     18,
        Name:    "name",
    }
    fmt.Println(stu)

	// 在赋值的时候,字段名可以忽略
	stu2 := Student{20, "new name"} 
    fmt.Println(stu2)

    return
}

上述代码 5 行声明了一个Student的结构体。而在第 11 行,通过指定每个字段名的值,我们定义了结构体变量 stu。字段名的顺序不一定要与声明结构体类型时的顺序相同。在这里,我们改变了 Age 的位置,将其移到了末尾。这样做也不会有任何的问题。

但是在第 18 行。定义 stu2 时我们省略了字段名。在这种情况下,就需要保证字段名的顺序与声明结构体时的顺序相同。请不要使用这种语法,因为它很难确定哪个值是哪个字段的。我们在这里指定这种格式只是为了理解这也是一种有效的语法:)

上述代码输出如下:

{18 name}
{20 new name}

创建匿名结构体

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

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的内容。在第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() {  
    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 语言允许我们在访问 firstName 字段时,可以使用 emp8.firstName 来代替显式的解引用 (*emp8).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 

匿名字段

可以创建具有仅包含类型而没有字段名称的字段的结构。这些类型的字段称为匿名字段。

下面的代码片段创建了一个结构Person,它有两个匿名字段stringint

type Person struct {  
    string
    int
}

即使匿名字段没有明确的名称,默认情况下匿名字段的名称就是其类型的名称。例如,在上面的 Person结构中,虽然字段是匿名的,但默认情况下它们采用字段类型的名称。所以Person结构体有 2 个字段,分别为stringint.

package main
 
import (  
    "fmt"
)
 
type Person struct {  
    string
    int
}
 
func main() {  
    p1 := Person{
        string: "naveen",
        int:    50,
    }
    fmt.Println(p1.string)
    fmt.Println(p1.int)
}

在上面程序的第 17 行和第 18 行,我们访问了 Person 结构体的匿名字段,我们把字段类型作为字段名,分别为 “string” 和 “int”。上面程序的输出如下:

naveen  
50  

嵌套结构体

一个结构可能包含一个字段,而该字段又是一个结构。这些类型的结构称为嵌套结构。

package main
 
import (  
    "fmt"
)
 
type Address struct {  
    city  string
    state string
}
 
type Person struct {  
    name    string
    age     int
    address Address
}
 
func main() {  
    p := Person{
        name: "Naveen",
        age:  50,
        address: Address{
            city:  "Chicago",
            state: "Illinois",
        },
    }
 
    fmt.Println("Name:", p.name)
    fmt.Println("Age:", p.age)
    fmt.Println("City:", p.address.city)
    fmt.Println("State:", p.address.state)
}

上述程序中Person的结构有一个字段address,该字段address又是一个结构。该程序打印:

Name: Naveen  
Age: 50  
City: Chicago  
State: Illinois

注意:

  • 当定义一个结构体变量,但是没有给它提供初始值,则对应的字段被赋予它们各自类型的零值。
  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

极简网络科技

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值