Go: struct 结构体类型和指针【学习笔记记录】

简介: 本文是Go语言中struct结构体类型和指针的学习笔记,包括结构体的定义、成员访问、使用匿名字段,以及指针变量的声明使用、指针数组定义使用和函数传参修改值的方法。

struct 结构体类型

Go 语言中数组可以存储同一类型的数据,但在结构体中我们可以为不同项定义不同的数据类型。

结构体是由一系列具有相同类型或不同类型的数据构成的数据集合。

结构体表示一项记录,比如所有的学生可以看作是一个结构体,每个学生包含,姓名,性别,年龄,学号…的属性。

1. 定义结构体

结构体定义需要使用 type 和 struct 语句。struct 语句定义一个新的数据类型,结构体中有一个或多个成员。type 语句设定了结构体的名称。

type 结构体名 struct {
   
       // 成员变量
    成员变量名 数据类型
}

2. 访问结构体成员

在Go中访问结构体成员,也是通过 ”结构体.成员变量名“ 的方式来访问。

结构体.成员名

例如创建一个学生结构体,然后对其进行初始化赋值,接着打印出对应结构体的详细信息

package main

import "fmt"

// 结构体的使用

// 1.struct 指明结构体类型 ,type 指明 数据类型
type student struct {
   
    name string
    sex  string
    age  int
    sid  int
}

func main() {
   
    // 结构体对象创建格式
    var st1 = student{
   }
    st2 := student{
   }
    printSt(st1)
    printSt(st2)
    // 赋值初始化
    st1.sex = "男"
    st1.name = "黄飞鸿"
    st1.age = 18
    st1.sid = 2020040413
    // 赋值初始化
    st2.sex = "男"
    st2.name = "叶问"
    st2.age = 18
    st2.sid = 2020040414
    printSt(st1)
    printSt(st2)
    // 声明并且同时赋值初始化
    var st4 = student{
   name: "李四", age: 22, sex: "男", sid: 2020040415}
    st5 := student{
   name: "张三", age: 22, sex: "男", sid: 2020040416}
    printSt(st4)
    printSt(st5)
}

// 打印结构体成员的函数
func printSt(st student) {
   
    fmt.Printf("学生信息:姓名%v\t,性别:%v\t,年龄:%d\t,学号:%d\t\n",
        st.name, st.sex, st.age, st.sid)
}

运行输出如下:

学生信息:姓名   ,性别:  ,年龄:0 ,学号:0
学生信息:姓名   ,性别:  ,年龄:0 ,学号:0
学生信息:姓名黄飞鸿     ,性别:男        ,年龄:18        ,学号:2020040413
学生信息:姓名叶问       ,性别:男        ,年龄:18        ,学号:2020040414
学生信息:姓名李四       ,性别:男        ,年龄:22        ,学号:2020040415
学生信息:姓名张三       ,性别:男        ,年龄:22        ,学号:2020040416

这里只是简单的单个结构体的使用,一般我们都使用结构体嵌套的方式,以更好的对实体进行描述。

3. 结构体的使用及匿名字段

Go支持只提供类型,而不写字段名的方式,也就是匿名字段,也称为嵌入字段(在上面的方式中,结构体成员变量名与数据类型一一对应)。

比如,创建一个People的结构体,然后People是一个很大的范围,学生是其中的一个结构体。

package main

import "fmt"

type People struct{
   
    name string
    sex string
    age int
}

type Student struct{
   
    People // 匿名字段的使用,只写数据类型,不写字段名
    sid int
}

func main() {
   
    var st1 = Student{
   People{
   name: "叶问", sex: "男", age: 23}, 10001}
    printSt(st1)
}

func printSt(st Student) {
   
    fmt.Printf("学生信息:姓名%v\t,性别:%v\t,年龄:%d\t,学号:%d\t\n",
        st.name, st.sex, st.age, st.sid)
}

当然,在结构体中其他的普通字段也可以使用匿名字段

在复合结构体中,若存在相同名称的字段,优先访问外层结构体的重名字段,若是想访问内层的重名字段,则需要以内层结构体.成员变量的方式来访问。

type people struct {
   
    name string 
    sex string
}
type student struct {
   
    people 
    name string
    sid int
}

访问外部的重名成员字段

结构体.成员变量字段

访问内部的重名成员字段

结构体.内嵌结构体.成员变量字段

例如下面的例子:

// 创建一个struct结构体
var st1 = student{
   people{
   "张三","男"},"李四",10001}
// 访问外部重名成员字段
print(st1.name) // 李四
print(st1.people.name) //张三

指针

Go 语言的取地址符是 &,放到一个变量前使用就会返回相应变量的内存地址。

一个指针变量指向了一个值的内存地址。类似于变量和常量,在使用指针前需要声明指针。

1. 指针变量的声明及使用

指针变量声明的格式如下:

var 指针名 *数据类型

指针使用流程:

  • 定义指针变量。
  • 为指针变量赋值。
  • 访问指针变量中指向地址的值。

在指针类型前面加上 * 号(前缀)来获取指针所指向的内容。

使用如下:

package main

func main() {
   
    var a = 10
    println(a) // 10
    var p *int
    // 将指针p指向变量a
    p = &a
    // 对指针p指向的值进行更改,a的值也会发生更改
    *p = 11
    println(a) // 11
    println(*p) // 11
}

2. 指针数组的定义及使用

指针数组的声明定义格式:

var 指针数组名 [size] *数据类型

与指针变量声明格式基本一致,只是指针数组多了数组长度。

// 定义一个整型数组,然后使用指针数组分别指向里面的每个数组元素
var numbers = []int {
   11,22,33}
var ptrs [3]*int
for i:= range numbers{
   
    ptrs[i] = &numbers[i]
}
for j:= range ptrs{
   
    println(*ptrs[j])
}
// 11
// 22 
// 33

3. 函数传参修改值

还是指针的特性,直接指向值。函数传参修改值,其实就是在调用函数时,传入地址即可。

比如,一个交换两个变量的值

package main

import "fmt"

func main() {
   
    var a int = 10
    var b int = 20
    fmt.Printf("a:%d\t,b:%d\t\n", a, b)
    swap(&a, &b)
    fmt.Printf("a:%d\t,b:%d\t\n", a, b)
}

func swap(ptr1 *int, ptr2 *int) {
   
    var temp int
    temp = *ptr1
    *ptr1 = *ptr2
    *ptr2 = temp
}
// a:10    ,b:20
// a:20    ,b:10

相关文章
|
25天前
|
存储 Rust Go
Go nil 空结构体 空接口有什么区别?
本文介绍了Go语言中的`nil`、空结构体和空接口的区别。`nil`是预定义的零值变量,适用于指针、管道等类型;空结构体大小为0,多个空结构体实例指向同一地址;空接口由`_type`和`data`字段组成,仅当两者均为`nil`时,空接口才为`nil`。
Go nil 空结构体 空接口有什么区别?
|
2月前
|
C语言 C++
【C语言】指针篇-一篇搞定不同类型指针变量-必读指南(3/5)
【C语言】指针篇-一篇搞定不同类型指针变量-必读指南(3/5)
|
3月前
|
Go
Go to Learn Go之结构体
Go to Learn Go之结构体
40 5
Go语言的条件控制语句及循环语句的学习笔记
本文是Go语言的条件控制语句和循环语句的学习笔记,涵盖了if语句、if-else语句、if嵌套语句、switch语句、select语句以及for循环和相关循环控制语句的使用方法。
Go语言的条件控制语句及循环语句的学习笔记
|
3月前
|
存储 Shell Go
Go语言结构体和元组全面解析
Go语言结构体和元组全面解析
|
3月前
|
存储 Go
Go to Learn Go之指针
Go to Learn Go之指针
27 0
|
3月前
|
人工智能 算法 搜索推荐
Go学习笔记-代码调
近年来,人工智能技术飞速发展,Cody作为由Sourcegraph开发的一款AI驱动编码助手,应运而生。它不仅提供代码预测与补全,还能深度理解代码上下文,为开发者提供准确建议,提升编码效率和质量。Cody能识别潜在错误并提出修复建议,缩短调试时间,同时进行智能代码审查,帮助优化代码结构和风格。未来,随着AI技术进步,Cody将不断学习优化,成为开发者不可或缺的伙伴,推动编程领域的创新与发展。
34 0
|
Go Python
Golang学习笔记之方法(method)
原文作者:学生黄哲链接:https://www.jianshu.com/p/6e615b08cfaf來源:简书简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。 ⽅法总是绑定对象实例,并隐式将实例作为第⼀实参 (receiver)。
1401 0
|
1天前
|
存储 Go 索引
go语言使用for循环遍历
go语言使用for循环遍历
15 7
|
1天前
|
开发框架 Go 计算机视觉
纯Go语言开发人脸检测、瞳孔/眼睛定位与面部特征检测插件-助力GoFly快速开发框架
开发纯go插件的原因是因为目前 Go 生态系统中几乎所有现有的人脸检测解决方案都是纯粹绑定到一些 C/C++ 库,如 OpenCV 或 dlib,但通过 cgo 调用 C 程序会引入巨大的延迟,并在性能方面产生显著的权衡。此外,在许多情况下,在各种平台上安装 OpenCV 是很麻烦的。使用纯Go开发的插件不仅在开发时方便,在项目部署和项目维护也能省很多时间精力。