Skip to content
🗂️ 文章分类: GO  
📅 文章创建时间: 2026-04-24
🕘️ 文章最后更新时间:2026-04-24

[toc]

GO笔记1

目前最新的GO稳定版本为1.26.2

Go是从2007年末由Robert Griesemer, Rob Pike, Ken Thompson主持开发,后来还加入了Ian Lance Taylor, Russ Cox等人,并最终于2009年11月开源,在2012年早些时候发布了Go 1稳定版本。现在Go的开发已经是完全开放的,并且拥有一个活跃的社区。

GO安装

GO官网截图 go_2026-04-29_115203_641.png

GO官网地址 https://golang.google.cn/

Go安装包下载地址 https://golang.google.cn/dl/

windows安装GO的话,下载msi文件,然后双击安装即可。 go_2026-04-29_115340_905.png

GO基础语法

行分隔符

在 Go 程序中,一行代表一个语句结束。每个语句不需要像 C 家族中的其它语言一样以分号;结尾,因为这些工作都将由 Go 编译器自动完成。

如果你打算将多个语句写在同一行,它们则必须使用;人为区分。

示例如下

go
fmt.Println("Hello, World!")
fmt.Println("菜鸟教程:runoob.com")

注释

Go 支持两种注释:单行注释和多行注释。

  • 单行注释以 // 开头,直到行末。
  • 多行注释也叫块注释,以 /* 开头,并以 */ 结尾。

示例如下

go
// 单行注释

/*
 多行注释
 */
 
/* 这是一个多行注释 */

标识符和关键字

标识符用来命名变量、类型等程序实体。一个标识符实际上就是一个或是多个字母(A~Z和a~z)数字(0~9)、下划线_组成的序列,但是第一个字符必须是字母或下划线而不能是数字。

示例如下

go
// a 就是一个标识符
var a int

关键字就是 Go 语言中官方已经定义好的、不能被用户使用的标识符。

常用的关键字有:

go
break	default	func	interface	select
case	defer	go	map	struct
chan	else	goto	package	switch
const	fallthrough	if	range	type
continue	for	import	return	var

格式化字符串

Go 语言中使用 fmt.Sprintf 或 fmt.Printf 格式化字符串并赋值给新串。

  • fmt.Sprintf 根据格式化参数生成格式化的字符串并返回该字符串。
  • fmt.Printf 根据格式化参数生成格式化的字符串并写入标准输出。

示例如下

go
// 定义包名
package main
//导入fmt包,用于格式化输出
import "fmt"

// main函数,程序入口
func main() {
   // %d 表示整型数字,%s 表示字符串
    var stockcode=123
    var enddate="2020-12-31"
    var url="Code=%d&endDate=%s"
    var target_url=fmt.Sprintf(url,stockcode,enddate)
    fmt.Println(target_url)
    // 输出结果为 Code=123&endDate=2020-12-31


    fmt.Printf(url,stockcode,enddate)
    // 输出结果为 Code=123&endDate=2020-12-31
}

GO语言-数据类型

在 Go 编程语言中,数据类型用于声明函数和变量。数据类型的出现是为了把数据分成各个内存大小不同的数据。

Go 语言按类别有以下几种数据类型。

  • 数字类型:包含整型 int 和浮点型 float32、float64。默认值为0。
  • 字符串类型:包含单引号和双引号的字符串。默认值为空字符串""。
  • 布尔类型:只有 true 和 false 两个值。默认值为false。
  • 派生类型:
    • (a) 指针类型(Pointer)
    • (b) 数组类型(Array)
    • (c) 结构化类型(struct)
    • (d) Channel 类型
    • (e) 函数类型
    • (f) 切片类型
    • (g) 接口类型(interface)
    • (h) Map 类型

数字类型

数字类型:包含整型 int 和浮点型 float32、float64。具体有以下几种:

序号类型和描述
1uint8 无符号 8 位整型 (0 到 255)
2uint16 无符号 16 位整型 (0 到 65535)
3uint32 无符号 32 位整型 (0 到 4294967295)
4uint64 无符号 64 位整型 (0 到 18446744073709551615)
5int8 有符号 8 位整型 (-128 到 127)
6int16 有符号 16 位整型 (-32768 到 32767)
7int32 有符号 32 位整型 (-2147483648 到 2147483647)
8int64 有符号 64 位整型 (-9223372036854775808 到 9223372036854775807)

浮点型

浮点型:包含 float32 和 float64。具体有以下几种:

序号类型和描述
1float32 32 位浮点型 (4 字节)
2float64 64 位浮点型 (8 字节)
3complex64 32 位实数和虚数 (8 字节)
4complex128 64 位实数和虚数 (16 字节)

变量

Go 语言变量名由字母、数字、下划线组成,其中首个字符不能为数字。

声明变量的一般形式是使用 var 关键字。

声明变量有几种方式。

方式1:声明单个或多个变量

如果变量没有初始化,则变量默认为该数据类型默认的值。

示例如下

go
// 语法
var 变量名 数据类型

// 声明一个字符串变量 a
var a string
a = "123"

// 声明两个整型变量 b 和 c
var b, c int
b = 1
c = 2

方式2:声明变量并初始化

示例如下

go
// 语法
var 变量名 数据类型 =

// 声明一个字符串变量 a,并赋值为 "123"
var a string = "123"
// 声明两个整型变量 b 和 c,并赋值为 1 和 2
var b, c int = 1, 2

方式3: 声明变量,无需填写数据类型,会根据值自行判定变量类型

当声明变量的时候,若不指定数据类型,则根据值自行判定变量类型。

go
// 语法
var 变量名 =

// 声明一个变量 a,并赋值为 "123"。此时变量a的数据类型会被判定为字符串类型。
var a = "123"
// 声明两个变量 b 和 c,并赋值为 1 和 2。此时变量b和c的数据类型会被判定为整型。
var b, c = 1, 2

方式4: 通过短变量声明操作符 := 符号来声明变量

注意:
  1. 如果变量已经使用 var 声明过了,再使用短变量声明操作符 := 声明该变量,就产生编译错误。
  2. 短变量声明操作符 := 符号用于在函数体内部声明变量并赋值。

示例如下

go
// 语法
变量名 :=
//相当于
var 变量名 数据类型 =


package main
import "fmt"
func main() {
    // 声明一个变量 a,并赋值为 "123"。此时变量a的数据类型会被判定为字符串类型。
    a := "123"

    // 声明三个变量b、c、d,并赋值为 5、7、"abc"。此时变量b、c、d的数据类型会被判定为整型、整型、字符串类型。
    b, c, d := 5, 7, "abc"
}

常量

常量是一个简单值的标识符,在程序运行时,不会被修改的量。

常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型。

声明常量

go
// 语法
const 常量名 数据类型名称(可选) =

package main
import "fmt"
func main() {
    // 声明一个常量 LENGTH,并赋值为 10。
    const LENGTH int = 10
    // 声明一个常量 WIDTH,并赋值为 5。
    const WIDTH = 5

    //声明常量 a、b、c,并赋值为 1、false、"str"。
    const a, b, c = 1, false, "str" // 多重赋值

    // 声明一个变量 area,并赋值为 LENGTH * WIDTH。
    var area int
    area = LENGTH * WIDTH
}

运算符

运算符用于在程序运行时执行数学或逻辑运算。

算术运算符

下表列出了所有Go语言的算术运算符。假定 A 值为 10,B 值为 20。

运算符描述实例
+相加A + B 输出结果 30
-相减A - B 输出结果 -10
*相乘A * B 输出结果 200
/相除B / A 输出结果 2
%求余B % A 输出结果 0
++自增A++ 输出结果 11
--自减A-- 输出结果 9

示例代码如下

go
package main
import "fmt"

func main() {
   var a int = 21
   var b int = 10
   var c int

   c = a + b // 31
   c = a - b // -10
   c = a * b // 210
   c = a / b // 2
   c = a % b // 1
   a++ // 22
   a-- // 21
}

关系运算符

下表列出了所有Go语言的关系运算符。假定 A 值为 10,B 值为 20。

运算符描述实例
==检查两个值是否相等,如果相等返回 True 否则返回 False。(A == B) 为 False
!=检查两个值是否不相等,如果不相等返回 True 否则返回 False。(A != B) 为 True
>检查左边值是否大于右边值,如果是返回 True 否则返回 False。(A > B) 为 False
<检查左边值是否小于右边值,如果是返回 True 否则返回 False。(A < B) 为 True
>=检查左边值是否大于等于右边值,如果是返回 True 否则返回 False。(A >= B) 为 False
<=检查左边值是否小于等于右边值,如果是返回 True 否则返回 False。(A <= B) 为 True

逻辑运算符

go_2026-04-29_170443_129.png

示例代码如下

go
package main
import "fmt"

func main() {
   var a bool = true
   var b bool = false
   if ( a && b ) {
      fmt.Printf("第一行 - 条件为 true\n" )
   }
   if ( a || b ) {
      fmt.Printf("第二行 - 条件为 true\n" )
   }
   /* 修改 a 和 b 的值 */
   a = false
   b = true
   if ( a && b ) {
      fmt.Printf("第三行 - 条件为 true\n" )
   } else {
      fmt.Printf("第三行 - 条件为 false\n" )
   }
   if ( !(a && b) ) {
      fmt.Printf("第四行 - 条件为 true\n" )
   }
}

赋值运算符

go_2026-04-29_172126_339.png

条件语句

Go 语言提供了以下几种条件判断语句:

语句描述
if 语句if 语句 由一个布尔表达式后紧跟一个或多个语句组成。
if...else 语句if 语句 后可以使用可选的 else 语句, else 语句中的表达式在布尔表达式为 false 时执行。
if 嵌套语句你可以在 if 或 else if 语句中嵌入一个或多个 if 或 else if 语句。
switch语句 switch 语句用于基于不同条件执行不同动作。
select语句 select 语句类似于 switch 语句,但是select会随机执行一个可运行的case。如果没有case可运行,它将阻塞,直到有case可运行。

if 语句

If 语句在布尔表达式为 true 时,其后紧跟的语句块执行,如果为 false 则不执行。

go
// 语法
if 布尔表达式 {
   /* 在布尔表达式为 true 时执行 */
}

package main
import "fmt"
func main() {
   /* 定义局部变量 */
   var a int = 10
 
   /* 使用 if 语句判断布尔表达式 */
   if a < 20 {
       /* 如果条件为 true 则执行以下语句 */
       fmt.Printf("a 小于 20\n" )
   }
   fmt.Printf("a 的值为 : %d\n", a)
}

// 输出结果
// a 小于 20
// a 的值为 : 10

if...else 语句

if 语句 后可以使用可选的 else 语句, else 语句中的表达式在布尔表达式为 false 时执行。

go
// 语法
if 布尔表达式 {
   /* 在布尔表达式为 true 时执行 */
} else {
  /* 在布尔表达式为 false 时执行 */
}

package main
import "fmt"
func main() {
   /* 局部变量定义 */
   var a int = 100;
 
   /* 判断布尔表达式 */
   if a < 20 {
       /* 如果条件为 true 则执行以下语句 */
       fmt.Printf("a 小于 20\n" );
   } else {
       /* 如果条件为 false 则执行以下语句 */
       fmt.Printf("a 不小于 20\n" );
   }
   fmt.Printf("a 的值为 : %d\n", a);

}

// 输出结果
// a 不小于 20
// a 的值为 : 100

if 嵌套 语句

你可以在 if 或 else if 语句中嵌入一个或多个 if 或 else if 语句。

go
// 语法
if 布尔表达式 1 {
   /* 在布尔表达式 1 为 true 时执行 */
   if 布尔表达式 2 {
      /* 在布尔表达式 2 为 true 时执行 */
   }
}

package main
import "fmt"
func main() {
   /* 定义局部变量 */
   var a int = 100
   var b int = 200
 
   /* 判断条件 */
   if a == 100 {
       /* if 条件语句为 true 执行 */
       if b == 200 {
          /* if 条件语句为 true 执行 */
          fmt.Printf("a 的值为 100 , b 的值为 200\n" );
       }
   }
   fmt.Printf("a 值为 : %d\n", a );
   fmt.Printf("b 值为 : %d\n", b );
}

// 输出结果
// a 的值为 100 , b 的值为 200
// a 值为 : 100
// b 值为 : 200

switch 语句

switch 语句用于基于不同条件执行不同动作,每一个 case 分支都是唯一的。switch 语句执行的过程从上至下,直到找到匹配项,匹配项后面也不需要再加 break。

go
// 语法
switch var1 {
    case val1:
        ...
    case val2:
        ...
    default:
        ...
}

package main
import "fmt"
func main() {
   /* 定义局部变量 */
   var grade string = "B"
   var marks int = 90

   switch marks {
      case 90: grade = "A"
      case 80: grade = "B"
      case 50,60,70 : grade = "C"
      default: grade = "D"  
   }

   switch {
      case grade == "A" :
         fmt.Printf("优秀!\n" )     
      case grade == "B", grade == "C" :
         fmt.Printf("良好\n" )      
      case grade == "D" :
         fmt.Printf("及格\n" )      
      case grade == "F":
         fmt.Printf("不及格\n" )
      default:
         fmt.Printf("差\n" );
   }
   fmt.Printf("你的等级是 %s\n", grade );      
}
// 输出结果
// 优秀!
// 你的等级是 A

fallthrough

使用 fallthrough 会强制执行后面的 case 语句。

如果 case 带有 fallthrough,程序会继续执行下一条 case,且它不会去判断下一个 case 的表达式是否为 true。

go
package main
import "fmt"
func main() {

    switch {
        case false:
                fmt.Println("1、case 条件语句为 false")
                fallthrough  
        case true:
                fmt.Println("2、case 条件语句为 true")
                fallthrough
        case false:
                fmt.Println("3、case 条件语句为 false")
                fallthrough
        case true:
                fmt.Println("4、case 条件语句为 true")
        case false:
                fmt.Println("5、case 条件语句为 false")
                fallthrough
        default:
                fmt.Println("6、默认 case")
    }
}

// 输出结果
// 2、case 条件语句为 true
// 3、case 条件语句为 false
// 4、case 条件语句为 true

select 语句

select 是 Go 中的一个控制结构,类似于 switch 语句。

select 语句只能用于通道操作,每个 case 必须是一个通道操作,要么是发送要么是接收。select 语句会监听所有指定的通道上的操作,一旦其中一个通道准备好就会执行相应的代码块。

如果多个通道都准备好,那么 select 语句会随机选择一个通道执行。如果所有通道都没有准备好,那么执行 default 块中的代码。

go
// 语法
select {
  case <- channel1:
    // 执行的代码
  case value := <- channel2:
    // 执行的代码
  case channel3 <- value:
    // 执行的代码

    // 你可以定义任意数量的 case

  default:
    // 所有通道都没有准备好,执行的代码
}

以下描述了 select 语句的语法:

  • 每个 case 都必须是一个通道操作
  • 所有 channel 表达式都会被求值
  • 所有被发送的表达式都会被求值
  • 如果有任意某个通道可以进行,它就执行,其他被忽略。
  • 如果有多个 case 都可以运行,select 会随机公平地选出一个执行,其他不会执行。 否则:
    • 如果有 default 子句,则执行该语句。
    • 如果没有 default 子句,select 将阻塞,直到某个通道可以运行;Go 不会重新对 channel 或值进行求值。

示例代码

go
package main
import ("fmt""time")

func main() {

    c1 := make(chan string)
    c2 := make(chan string)

    go func() {
        time.Sleep(1 * time.Second)
        c1 <- "one"
    }()
    go func() {
        time.Sleep(2 * time.Second)
        c2 <- "two"
    }()

    for i := 0; i < 2; i++ {
        select {
        case msg1 := <-c1:
            fmt.Println("received", msg1)
        case msg2 := <-c2:
            fmt.Println("received", msg2)
        }
    }
}
// 输出结果
// received one
// received two

循环语句

for 循环语句

for 循环是一个循环控制结构,可以执行指定次数的循环。

Go 语言的 For 循环语句有 3 种语法形式。

语法1

go
// 语法1
for init; condition; post { 
       // 循环体
}
// init: 一般为赋值表达式,给控制变量赋初值;
// condition: 关系表达式或逻辑表达式,循环控制条件;
// post: 一般为赋值表达式,给控制变量增量或减量。

语法1的for循环语句的执行过程:

  1. 执行 init 表达式,初始化控制变量。
  2. 执行 condition 表达式,判断是否继续循环。若为 true,则执行循环体;否则为 false,退出循环。
  3. 执行 post 表达式,更新控制变量的值。
  4. 跳转到步骤 2,重复执行循环。直到 condition 表达式为 false 或循环体中使用 break 语句退出循环。

示例代码如下

go
package main
import "fmt"
func main() {
   // 输出1 到 10 的数字
   for i := 0; i <= 10; i++ {
      fmt.Println(i)
   }
}

语法2

类似 while 循环。

go
//语法2
for condition {
       // 循环体
}

//示例代码
package main
import "fmt"
func main() {
   i := 1
   // 这样写也可以,更像 While 语句形式
   for i <= 10{
      fmt.Println(i)
      i++
   }
}

语法3

当没有循环控制条件时,使用 for 循环。循环体中的代码会无限执行,类似无限循环。

go
// 语法3
for {
       // 循环体
}

//示例代码
package main
import "fmt"
func main() {
   i := 0
   for {
      fmt.Println(i)
   }
}

for range 循环语句

for 循环的 range 格式可以对 slice、map、数组、字符串等进行迭代循环。

代码中的 key 和 value 是可以省略。

go
// 语法1
for key, value := range oldMap {
   // 循环体
}

// 如果只想读取 value,语法如下
for _, value := range oldMap {
   // 循环体
}

// 如果只想读取 key,语法如下
for key := range oldMap {
   // 循环体
}

//示例代码
package main
import "fmt"
func main() {
   strings := []string{"google", "runoob"}
   for i, s := range strings {
      fmt.Println(i, s)
   }

   //输出结果
   // 0 google
   // 1 runoob 

   numbers := [4]int{1, 2, 3, 5} 
   for i,x:= range numbers {
      fmt.Printf("第 %d 位 x 的值 = %d\n", i,x)
   }  
   //输出结果
   // 第 0 位 x 的值 = 1
   // 第 1 位 x 的值 = 2
   // 第 2 位 x 的值 = 3
   // 第 3 位 x 的值 = 5
}

break 语句

在 Go 语言中,break 语句用于终止当前循环或者 switch 语句的执行,并跳出该循环或者 switch 语句的代码块。

break 语句可以用于以下几个方面:。

  • 用于循环语句中跳出循环,并开始执行循环之后的语句。
  • break 在 switch 语句中在执行一条 case 后跳出语句的作用。
  • break 可应用在 select 语句中。
  • 在多重循环中,可以用标号 label 标出想 break 的循环。
go
// 示例代码1  在 for 循环中使用 break 语句
package main
import "fmt"
func main() {
   for i := 0; i < 10; i++ {
      if i == 5 {
         break //当i等于5时,跳出循环
      }
      fmt.Println(i)
   }
}


// 示例代码2  在 switch 语句中使用 break 语句
func main2() {
    day := "Tuesday"
    switch day {
      case "Monday":
         fmt.Println("It's Monday.")
      case "Tuesday":
         fmt.Println("It's Tuesday.")
         break // 跳出 switch 语句
      case "Wednesday":
         fmt.Println("It's Wednesday.")
    }
}

continue 语句

continue 语句用于跳过当前循环的剩余语句,继续执行下一次循环。

go
//示例代码
package main
import "fmt"
func main() {
   /* 定义局部变量 */
   var a int = 10

   /* for 循环 */
   for a < 20 {
      if a == 15 {
         /* 跳过此次循环,继续执行下一次循环。 */
         a = a + 1;
         continue;
      }
      fmt.Printf("a 的值为 : %d\n", a);
      a++;     
   }  
}

goto 语句

Go 语言的 goto 语句可以无条件地转移到过程中指定的行。

goto 语句通常与条件语句配合使用。可用来实现条件转移, 构成循环,跳出循环体等功能。

但是,在结构化程序设计中一般不主张使用 goto 语句, 以免造成程序流程的混乱,使理解和调试程序都产生困难。

go
//语法格式
goto label;
..
.
label: statement;

//示例代码
// 在变量 a 等于 15 的时候直接转移到语句 LOOP 处
package main
import "fmt"
func main() {
   /* 定义局部变量 */
   var a int = 10

   /* 循环 */
   LOOP: for a < 20 {
      if a == 15 {
         /* 转移到语句 LOOP 处 */
         goto LOOP
      }
      fmt.Printf("a的值为 : %d\n", a)
      a++     
   }  
}

函数

函数是基本的代码块,用于执行一个任务。你可以通过函数来划分不同功能,逻辑上每个函数执行的是指定的任务。

Go 语言最少有个 main() 函数。

函数定义(函数声明)

go
// 语法格式
func 函数名称( [参数列表] ) [返回类型] {
   函数体
}
  • func:函数由 func 开始声明。
  • 函数名称:函数的名称,用于调用函数。
  • 参数列表:参数列表指定的是参数类型、顺序、及参数个数。参数是可选的,也就是说函数也可以不包含参数。
  • 返回类型:函数的返回类型,用于返回数据。有些函数是不需要返回值的,这种情况下 return_types 不是必须的。
  • 函数体:函数的代码块,用于执行任务。
go
// 示例代码
/* 函数返回两个数的最大值 */
func max(num1, num2 int) int {
   /* 声明局部变量 */
   var result int

   if (num1 > num2) {
      result = num1
   } else {
      result = num2
   }
   return result 
}

函数调用

当创建函数时,你定义了函数需要做什么,通过调用该函数来执行指定任务。

go
// 示例代码
package main
import "fmt"

// 主函数
func main() {
   /* 定义局部变量 */
   var a int = 100
   var b int = 200
   var ret int

   /* 调用max函数并返回最大值 */
   ret = max(a, b)

   fmt.Printf( "最大值是 : %d\n", ret )
   // 输出结果:最大值是 : 200
}

/* 函数返回两个数的最大值 */
func max(num1, num2 int) int {
   /* 定义局部变量 */
   var result int
   if (num1 > num2) {
      result = num1
   } else {
      result = num2
   }
   return result 
}

函数返回多个值

Go 函数可以返回多个值。

go
package main
import "fmt"
//swap函数,交换两个字符串的值,返回交换后的两个字符串
func swap(x, y string) (string, string) {
   return y, x
}

func main() {
   a, b := swap("Google", "Runoob")
   fmt.Println(a, b)
   // 输出结果:Runoob Google
}

函数参数-值传递

默认情况下,Go 语言使用的是值传递。

值传递是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。

go
// 示例代码
package main

import "fmt"

func main() {
   /* 定义局部变量 */
   var a int = 100
   var b int = 200

   fmt.Printf("交换前 a 的值为 : %d\n", a )
   fmt.Printf("交换前 b 的值为 : %d\n", b )

   /* 通过调用函数来交换值 */
   swap(a, b)

   fmt.Printf("交换后 a 的值 : %d\n", a )
   fmt.Printf("交换后 b 的值 : %d\n", b )


   //输出结果
   // 交换前 a 的值为 : 100
   // 交换前 b 的值为 : 200
   // 交换后 a 的值 : 100
   // 交换后 b 的值 : 200
}

// swap 函数,交换两个整数的值
func swap(x, y int) int {
   var temp int

   temp = x /* 保存 x 的值 */
   x = y    /* 将 y 值赋给 x */
   y = temp /* 将 temp 值赋给 y*/
   return temp;
}

函数参数-引用传递

引用传递是指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。

go
// 示例代码
package main

import "fmt"

func main() {
   /* 定义局部变量 */
   var a int = 100
   var b int= 200

   fmt.Printf("交换前,a 的值 : %d\n", a )
   fmt.Printf("交换前,b 的值 : %d\n", b )

   /* 调用 swap() 函数
   * &a 指向 a 指针,a 变量的地址
   * &b 指向 b 指针,b 变量的地址
   */
   swap(&a, &b)

   fmt.Printf("交换后,a 的值 : %d\n", a )
   fmt.Printf("交换后,b 的值 : %d\n", b )

   //输出结果
   // 交换前,a 的值 : 100
   // 交换前,b 的值 : 200
   // 交换后,a 的值 : 200
   // 交换后,b 的值 : 100
}

func swap(x *int, y *int) {
   var temp int
   temp = *x    /* 保存 x 地址上的值 */
   *x = *y      /* 将 y 值赋给 x */
   *y = temp    /* 将 temp 值赋给 y */
}