39-struct 结构体(一)

终于迎接来 Go 语言最最核心的数据类型 —— struct. 没错,这和 C 语言里的结构体几乎一模一样。不过 Go 里的结构体,会比 C 语言的结构多一些东西,这些后面再讲。

本文先简单认识一下 Go 的结构体是什么样子,以及怎么声明和定义。

1. 声明与定义

  • 例1
package main

import "fmt"

func main() {
    // 定义了一个变量 p,它是一个结构体对象。
    var p struct {
        id     int
        name   string
        age    int
        height int
    }

    p.name = "allen"
    p.age = 20
    p.height = 180
    fmt.Println(p)  // Output: {0 allen 20 180}
}

上面的代码定义了一个变量 p,类型是一个结构体,跟在 p 的后面。

如果另外一个地方也用到了和 p 同样类型的的结构体怎么办呢?没错,再写一遍就好啦^_^。开个玩笑,程序员是一种很懒的生物,肯定不愿意这么干。不知道你是否记得 type 关键字?如果忘记了,请看这一篇 《type 关键字》

要想复用一种结构体类型,可以这样写:

  • 例2
package main

import "fmt"

func main() {
    type person struct {
        id     int
        name   string
        age    int
        height int
    }

    // var p person    // 这种声明 ok
    // p := person{}   // 这种也 ok
    // p := person{5, "allen", 20, 180} // 这种使用字面量也是 ok 的
    p := person{id: 5} // 这种指定成员名称初始化值,也 ok
    p.name = "allen"
    p.age = 20
    p.height = 180
    fmt.Println(p)     // Output: {5 allen 20 180}
}

从例 2 中可以看到,使用 type 关键字给结构体取了个名字叫 person,后面我们就可以全部使用 person 这种新的类型来定义变量了。上面也列举了 4 种不同的定义变量的方式:

  • 使用 var 声明,这种是最传统的办法了
  • 使用 {} 声明一个空对象
  • 使用『字面量』初始化一个对象
  • 指定成员初始化值

有同学会问,这样行不行:

p := person{5, "allen"}

答:不行。使用字面量初始化,就必须给所有成员指定一个值。如果你只想给部分成员指定值,那就必须要把成员名字加上:

p := person{id:5, name: "allen"}

2. 访问 struct 成员

2.1 使用普通变量访问成员

在 Go 里访问 struct 成员像 C 语言一样,使用 . 号。例如:

fmt.Printf("id = %d\n", p.id) // 读取成员的值
p.id = 10 // 给成员赋值

2.2 使用指针访问成员

如果我们通过指针来访问结构体成员,应该是什么样的呢?

type person struct {
    id     int
    name   string
    age    int
    height int
}

p := person{5, "allen", 20, 180}
pp := &p
fmt.Println(pp)    // Output: &{5 allen 20 180}
fmt.Println(*pp)   // Output: {5 allen 20 180}

通过 pp 访问成员应该怎么办?下面是一种办法:

(*pp).name = "zoro"

不过,上面这种写法太繁琐,Go 里可以这样写:

pp.name = "zoro" // 是不是非常具有迷惑性?为什么不是 pp->name = "zoro" 这样多直观 TT

所以使用 . 语法,真的看不出来 . 前面的变量到底是普通变量,还是指针变量的指针。

使用指针的好处是,我们可以通过指针间接修改对象的值。比如可以让函数参数作为指针结构体变量的指针传进去,这样就可以在函数内部通过指针修改成员的值,从而改变函数外的结构体对象了。

2.3 指向结构体成员的指针

不仅可以取结构体变量的地址,还可以取结构体成员的地址:

type person struct {
    id     int
    name   string
    age    int
    height int
}

p := person{5, "allen", 20, 180}
pname := &p.name
*pname = "zoro" // 通过指针直接修改成员的值
fmt.Println(p)  // Output: {5 zoro 20 180}

3. 总结

  • 掌握结构体声明与定义
  • 掌握通过结构体指针访问成员的方法

猜你喜欢

转载自blog.csdn.net/q1007729991/article/details/80210631