golang 基础 - 详解

文档:https://www.topgoer.com/go%E5%9F%BA%E7%A1%80/%E6%8C%87%E9%92%88.html
https://books.studygolang.com/gopl-zh/ch7/ch7-03.html

命名

Go语言程序员推荐使用 驼峰式 命名

1、 变量定义

  • 对于引用类型的变量,我们在使用的时候不仅要声明它,还要为它分配内存空间,否则我们的值就没办法存储。包括指针、切片、映射、通道、函数和接口。这些类型在赋值或传递时只会复制地址而不是实际的值,从而避免了大量的数据复制,提高了性能
  • 对于值类型的声明不需要分配内存空间,是因为它们在声明的时候已经默认分配好了内存空间。包括基本数据类型(整型、浮点型、布尔型、字符型)和复合数据类型(数组、结构体)。这些类型在赋值或传递时会进行值拷贝。

需要注意的是在Go语言中支持对结构体指针直接使用.来访问结构体的成员。

2、 make和new

  • 使用new函数得到的是一个类型的指针,并且该指针对应的值为该类型的零值
  • make也是用于内存分配的,区别于new,它只用于slice、map以及chan的内存创建,而且它返回的类型就是这三个类型本身,而不是他们的指针类型,因为这三种类型就是引用类型,所以就没有必要返回他们的指针了
make和new的区别
  • 1.二者都是用来做内存分配的。
  • 2.make只用于slice、map以及channel的初始化,返回的还是这三个引用类型本身;
  • 3.而new用于类型的内存分配,并且内存对应的值为类型零值,返回的是指向类型的指针。

3、rune和byte

  • byte类型,代表了ASCII码的一个字符,uint8
  • rune类型,代表了utf-8类型,int32,需要处理中文、日文或其他复合字符时
// 遍历字符串
func traversalString() {
s := "pprof.cn博客"
for i := 0; i < len(s); i++ { //byte
fmt.Printf("%v(%c) ", s[i], s[i])
}
fmt.Println()
for _, r := range s { //rune
fmt.Printf("%v(%c) ", r, r)
}
fmt.Println()
}

字符串底层是一个byte数组,所以可以和[]byte类型相互转换。字符串是由byte字节组成,所以字符串的长度是byte字节的长度,一个rune字符由一个或多个byte组成。
字符串是不能修改的,要修改字符串,需要先将其转换成[]rune或[]byte

4、切片

和大多数编程语言类似,区间索引时,Go言里也采用左闭右开形式,即,区间包括第一个索引元素,不包括最后一个,因为这样可以简化逻辑。(译注:比如a = [1, 2, 3, 4, 5], a[0:3] = [1, 2, 3],不包含最后一个元素)。比如s[m:n]这个切片,0 ≤ m ≤ n ≤ len(s),包含n-m个元素。

5、结构体

使用&对结构体进行取地址操作相当于对该结构体类型进行了一次new实例化操作。
即:

p1 := new(person)
p2 := &person{}

6、方法与函数

方法与函数的区别是,函数不属于任何类型,方法属于特定的类型。

7、方法的接收者

  • 指针类型接收者:由于指针的特性,调用方法时修改接收者指针的任意成员变量,在方法结束后,修改都是有效的
  • 值类型接收者:会在代码运行时将接收者的值复制一份。在值类型接收者的方法中可以获取接收者的成员值,但修改操作只是针对副本,无法修改接收者变量本身

https://juejin.cn/post/7205023631167307834
使用值类型接收者实现方法时,编译器会自动实现对应的指针类型接收者的方法。而使用指针类型接收者实现方法时,编译器不会追加值类型接收者的方法实现。
T类型的参数上调用一个*T的方法是合法的,只要这个参数是一个变量;编译器隐式的获取了它的地址
在这里插入图片描述

8、闭包

闭包是由函数及其相关引用环境组合而成的实体,它引用了其函数体之外的变量,换句话说就是闭包=函数+引用环境。在Go语言中,闭包允许函数内部定义的匿名函数捕获并访问函数外部的变量,形成一个封闭的作用域。闭包能够捕获并“记住”定义它时的环境,因此函数内部的变量即使在函数执行结束后依然可以被访问和操作。两个特性

  • 保留状态:闭包允许函数保留其外部作用域中的变量状态。这使得闭包可以用来模拟对象的行为,维护私有状态
  • 参数化函数:闭包可以用于参数化函数,即将函数作为参数传递给另一个函数

使用时注意事项:

  • 变量生命周期
  • 并发安全性

参考文档:https://blog.csdn.net/weixin_53623989/article/details/135950921

9、defer

  • 关键字 defer 用于注册延迟调用。
  • 这些调用直到 return 前才被执。因此,可以用来做资源清理。
  • 多个defer语句,按先进后出的方式执行。
  • defer语句中的变量,在defer声明时就决定了。

10、recover

Go中可以抛出一个panic的异常,然后在defer中通过recover捕获这个异常,然后正常处理。

  • 利用recover处理panic指令,defer 必须放在 panic 之前定义,另外 recover 只有在 defer
    调用的函数中才有效。否则当panic时,recover无法捕获到panic,无法防止panic扩散。
  • recover处理异常后,逻辑并不会恢复到 panic 那个点去,函数跑到 defer 之后的那个点。
  • 多个 defer 会形成defer 栈,后定义的 defer 语句会被最先调用。

11、单元测试

  • 文件名必须以xx_test.go命名
  • 方法必须是Test[^a-z]开头
  • 方法参数必须 t *testing.T
  • 使用go test执行单元测试
posted @ 2025-12-16 16:05  yangykaifa  阅读(0)  评论(0)    收藏  举报