1587 字
8 分钟
go语言学习日记(持续更新中)
2025-10-04

go语言学习日记#

Day1#


变量声明#

go语言提供多种变量声明方式,一般使用mod来声明和赋值变量:

  1. var a int 初值为0
  2. var a = 3 (自动识别)
  3. var a int = 3
  4. a := 3 [这个就是mod用法]

还有多行赋值

var(
a int
b string
)

支持多返回值#

例如函数头应该长成这样

func test2()(int,int){ //匿名方式
return 123,456
}
func test1(a int,b int)(re1 int, re2 int){ //具体变量
//函数体里面的内容
re1 = a+b
re2 = a-b
return //后面不用加东西
}
func test1(a int,b int)(re1 int, re2 int){ //具体变量
//函数体里面的内容
return a+b,a-b //也可以这样
}
func main(){
reA,reB := test1(1,2)
}

包的导入#

在go里面导包是很经常的事情,很多东西都需要别的包里的函数来执行例如打印操作

import "fmt" //单行导入,需要双引号
import( //多行导入
fmt //不需要双引号
libA
libB
)
import( //别名导入
bag libA //此时libA的别名就是bag
_ libB //此时为匿名导入,即触发导包时的init函数但是不使用包的内容
. libC //此时libC的命名空间就导入到全局环境下了
)

注意在导入包的时候,路径要求要从go的环境路径的相对路径开始,或者是之后用go mod


严格语法#

在go语言里面,对于括号的位置是有严格要求的,对于函数体,if等一系列的需要{}的语句,其中的左括号必须跟在后面,不可以换行

func function1(){ //正确写法
//函数体
}
func function2()
{ //错误写法会报错
//函数体
}
if 条件表达式 { //正确写法
}
if 条件表达式
{ //错误写法
}
if 条件表达式{
}else{ //两个括号必须写在同一行
}

常量#

在go中,常量用的是const关键字,用const关键字的时候和var一样,同样需要指定数据类型

const a int

const还能用来做枚举,使用方法如下

const(
BEIJING = 0
SHANGHAI = 1
HANGZHOU = 2 //传统常量赋值枚举,注意此时是不用mod的
)

同样他可以像是数据库标识列一样自动展开

const(
BEIJING = iota //此时的值从0开始计数
SHANGHAI //自动赋值为1
TIANJIN //自动赋值为2
ZHEJIANG //自动赋值为3
)

iota可以进行初值改变例如:

const(
A = iota+65 //0+65
B //1+65
C //2+65
D //....
)

注意iota的改变值影响到下一个iota或者是结束之前,

const(
A = iota+65 //0+65
B //1+65
C //2+65
D //3+65
E = iota + 0 // 4+0
F // 5+0
)

Day2#

init函数#

在go语言里,不同包在被导入的时候会调用特殊的函数(即init函数)

可以使用init函数进行一些初始化

例如这是libA源码

package libA
func init(){
//初始化函数体
}

这个是main.go的源码

package main
import "libA" //此时已经触发了libA的init(),前提是编译能过
func main(){
//函数体,但是需要调用libA的内容
}

指针#

在go语言里面有着和c语言一样的指针调用机制,依旧基于以下运算符

  • &取地址符
  • *取值符
  • var point int* 声明

代码如下

package main
func main(){
a := 12
var pa *int = &a
}

defer语句#

在go语言中存在着其他的语言都没有的滞后触发的关键字,一般可以用于GC

defer语句修饰的函数都会在其他语句结束后,但是在当前的函数返回前被触发

例如

package main
import . "fmt"
func test1()(int){
println("1")
return 2
}
func main(){
defer println(test1())
println("3")
}

结果为132,因为defer的内容是打印test1的返回值所以2在最后,由于其实已经提前调用了,所以是1先出来


数组#

go语言中有着和c语言一样的定长数组,定义如下

package main
func main(){
var myArray [10]int //创建了10个长度的数组,其中的默认值都为0
}

关于定长的数组传参的问题,对于大形参可以向下兼容小实参


循环语句#

在go语言里面只有for循环,且使用方法是c语言的for或者是python的迭代器,示例如下

这个是c语言版本的

for i:=0;i<10;i++{ //
//循环体
}

这个是迭代器版本

for i,v := range myArray{
//循环体,其中的i就是index,v就是值
}

当然其中的一些东西也可以匿名,像是这样

for _,v := range myArray{
//循环体,当角标没有意义的时候
}

切片(动态数组)#

switch语句的fallthough还没记录

Day 3#

slice切片#

在go语言中,slice是比较常用的数组,有四种创建方式,并且用指针方式来验证是否为空

// 创建部分
slice1 = make([]int,3) //创建三个长度的slice (第一种)
var slice1 []int = make([]int,3) //加了var和前置的类型(第二种)
var slice1 []int //声明但是不初始化,此时的数组为空,slice1 == nil
func main(){
slice1 := []int{1,2,3} //使用mod和传统初始化(第三种)
slice1 := make([]int,3) //创建三个长度的切片,默认值为0
}
// 访问
slice1[0] = 999
判断非空
if slice1 != nil{
//判断体
}

概念:容量

在go语言中的容器是有容量和长度的概念的,len代表着当前的元素的个数,cap指的是不扩容最大长度为多少,如果元素被追加到超过cap,则会触发扩容机制

image-20251009083415531

追加

对于slice可以追加元素,追加的元素会位于slice的最后

func main(){
slice1 := make([]int,3,5)//三个参数分别为类型,长度和容量,现在打印出来就是[0,0,0] len = 3 cap = 5
slice1 = append(slice1,1)//新建一个追加了1的元素的slice然后赋值给slice1,此时的值为[0,0,0,1] len = 4 cap = 5
}

扩容

当某一次追加导致其len > cap 此时就会触发扩容,扩容的原理是将原有的大小扩大cap,扩容后内存空间将

若现有一个cap = 5 的slice在触发扩容后,slice的cap将会变成10

image-20251009091930098

这里的len应该在3那边,毕竟是抄的图

go语言学习日记(持续更新中)
https://blog.yuanguo.online/posts/go语言学习日记/
作者
yuanguolalala
发布于
2025-10-04
许可协议
CC BY-NC-SA 4.0
封面
示例歌曲
示例艺术家
封面
示例歌曲
示例艺术家
0:00 / 0:00