Go语言核心基础知识点整理

Go语言核心基础知识点整理

1. 环境配置

export GOROOT=/usr/local/go
export GOPATH=$HOME/go
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin

export GOPROXY=https://goproxy.cn,direct
go env -w GOPROXY=https://goproxy.cn,direct

2. 基础类型与零值

  • 布尔类型
    bool 不能参与数值运算,也不允许与其它类型强制转换。
  • 字符串与字符
    • byte = uint8,表示 ASCII 字符
    • rune = int32,表示 UTF‑8 字符
    • string 底层是 []byte,可与 []byte 互转
  • 运算符与类型转换
    • 自增、自减不是运算符,只能作为独立语句,而不是表达式
    • Go 语言中不支持 ++i--i 操作
    • Go 只有显式强制转换,无隐式转换
  • const
    • iota,常量计数器,在 const 中出现时重置为 0,每新增一行(空行不计)自动递增
    • 常量未使用是能编译通过的
  • 短变量
    • 使用变量简短声明符号 := 时,如果符号左边有多个变量,只需要保证至少有一个变量是新声明
    • 短变量声明 := 会在内部作用域创建新变量
  • nil
    • 预声明标识符(非关键字)
    • 指针、funcslicemapchan 的零值
    • 接口为 nil 当且仅当类型和值均为 nil
    • 允许对 nil 切片切片,返回 nil 切片
    • 允许 nil 数组指针遍历,len=0,直接跳过循环
  • 指针
    • 不能使用多级指针调用方法
    • 指针不可运算

3. 复合类型与内存分配

  • 数组
    固定长度,长度是类型的一部分,必须为常量。
  • 切片
    • 引用底层数组,自身是结构体(ptr/len/cap
    • 赋值是值拷贝,容量足够时共享底层数组;append 超出容量则重新分配并独立
    • 切片操作时,允许低索引大于长度但小于等于容量。但省略高索引时,高索引默认取长度,而不是容量
    • 声明后直接 append 是合法的(零值是 nilappend 会自动扩容分配内存)
  • map
    • map 是无序的
    • 删除不存在的键不会报错
    • 获取不存在的键返回值类型零值
    • map 中的结构体字段不可直接寻址,无法原地修改
    • cap()函数适用于数组、数组指针、slicechannel,不适用于map,可以使用len()返回map的元素个数
    • 只声明不初始化,直接赋值会 panic(零值是 nil,nil map 无法写入)
  • 内存分配
    • make:返回 Type 本身,仅用于 slicemapchan
    • new:返回 *Type,用于值类型(如 intstruct

4. 函数与流程控制

  • 参数传递
    • 只有值传递,传参时拷贝的是普通值本身,或引用类型(slicemapchan、指针)的“引用值”
    • 赋值规则允许底层类型相同且至少一个为未命名类型时直接赋值
    • Unnamed Type 不能作为方法的接收者
    • args ...int 是可变参数,函数内部视为切片;使用 slice 对象做变参时,必须展开(s...)。
  • defer 与 return
    • defer 在语句执行到该行时注册,后进先出执行
    • return 终止函数,但 defer 仍会在返回值返回前执行
    • return 三步:① 赋值返回值(无名返回值会创建临时变量)② 执行 defer ③ 返回最终值
    • 有名返回值可在 defer 中修改,无名返回值则不能
    • defer 语句在注册时,会立即计算所有参数/方法调用,直到最后一个方法延迟执行
    • 资源释放的 defer,一定要放在错误判断之后、正常流程之前
    • 命名返回值不能被子作用域完全遮蔽
  • fallthrough
    强制进入下一个 case,忽略其条件。
  • 多变量赋值
    • 先计算右值再统一赋值,支持直接交换:a, b = b, a
    • 计算等号左边的索引表达式和取址表达式,接着计算等号右边的表达式
  • 格式化输出
    fmt.Sprintf 返回格式化后的字符串。
  • 闭包
    闭包引用相同变量
  • init函数
    • init() 函数不能被其他函数调用,包括 main() 函数
    • init() 函数可以重名
  • main函数
    • 不能带参数,不能定义返回值,可以使用 flag 包来获取和解析命令行参数
    • 所在的包必须为 main 包

5. 面向接口与组合

  • 接口
    • 接口变量只能调用接口定义的方法,看不见底层结构体的其他方法
    • 实现 Error() string 即实现 error 接口
    • 接口比较时,动态类型不同,则直接返回false,不会panic
    • 赋值给接口(方法集严格判定):值类型的方法集,包含全部值类型接收者方法
    • 赋值给接口(方法集严格判定):指针类型的方法集,包含全部值类型接收者方法+全部指针类型接受者方法
  • 方法
    • 方法必须定义在同一包内
    • 字面量是不可寻址的,不能直接调用方法
    • 不可寻址的结构体不能调用带结构体指针接收者的方法
    • 方法值:将方法与特定的接收者实例绑定后得到的函数,调用该函数时无需再传递接收者
    • 方法表达式:将方法当作普通函数,但保留接收者作为第一个参数,后面依次是原方法的参数
    • 值接收者方法:无论调用者是值还是指针(会自动解引用),方法内操作的是值的副本,不影响原始变量
    • 指针接收者方法:无论调用者是值(会自动取地址)还是指针,方法内可通过指针修改原始变量
    • 当使用 type 声明一个新类型,它不会继承原有类型的方法集
  • 组合(非继承)
    • 无继承,只有组合(内嵌)
    • 内嵌结构体的方法不会被子结构体“覆盖”,调用时若自身无该方法才进入内嵌逻辑
    • 一旦进入内嵌方法,该方法内部只能看到内嵌结构体自己的方法
  • 结构体
    • 可直接用指针访问字段(语法糖)
    • 支持不写键的初始化:Person{"Alice", 20}
    • 只能比较相等(所有字段可比较时),不能比较大小
    • 不能使用短变量声明设置结构体字段值

6. 协程与通道

  • 协程
    • sync.WaitGroup 必须传指针,不能值传递
    • wg.Add(n) 必须在启动 go 之前调用
    • wg.Done() 建议用 defer 包裹,确保一定会执行
  • channel
    • 向已关闭的通道发送数据会引发 panic
    • 从已关闭的缓冲通道接收数据,返回已缓冲数据或者零值
    • 无论接收还是接收,nil 通道都会阻塞
    • close()只能关闭双向通道/只发 (chan<-) 通道
    • 单向通道不能转换为双向通道

7. 其他重要特性

  • 包与可见性
    包内名为 internal 的目录对包外不可见。
  • 比较规则
    • 可比较:bool、数值、string、指针、chaninterface(需动态类型可比较)、数组、结构体(元素/字段可比较时)
    • 不可比较:slicemapfunc、以及包含它们的结构体
  • 类型断言与类型选择
    仅能用于接口类型变量。
  • for range
    • 迭代变量是值副本:无论遍历数组、切片还是数组指针,v 都是元素的副本,修改 v 不影响原数据
    • 通过索引修改影响原数据:使用 a[i] 直接修改,会改变原数组或切片的对应元素
    • 遍历切片/数组指针时,v 是底层数组的实时值拷贝;遍历数组时,v 是基于数组副本的固定值
  • nil 的接口判定
    接口为 nil 必须类型和值同时为 nil
  • recover
    recover() 必须在 defer() 函数中直接调用才有效
  • goto
    goto 不能跳转到其他函数或者内层代码
posted @ 2026-03-27 23:44  wanghongwei-dev  阅读(4)  评论(0)    收藏  举报