Golang的核心开发团队
Go语言(又称Golang)是一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言,由罗伯特·格瑞史莫(Robert Griesemer)、罗布·派克(Rob Pike)及肯·汤普森(Ken Thompson)于2007年9月开始设计。

Golang的发展历程
Go语言发展历程如下:
说明一下: 目前Go每半年发布一个二级版本(即从a.x升级到a.y),各个版本详细的更新内容可以在Go官方网站查看。
Golang的特点
Go语言主要的特点如下:
Golang的应用领域
Go语言目前主要的应用领域如下:
下载SDK包
搭建Go开发环境,首先需要在Go官方网站下载Go的软件开发工具包(Software Development Kit,SDK)。如下:

点击Download按钮后,根据自己的环境选择对应的SDK安装包下载即可。这里我下载的是Windows操作系统下Go 1.20版本的开发包。如下:

开发包选择说明:
注:gox.xx.src.tar.gz中存放的是对应版本的Go源代码。
安装SDK包
由于我下载的是解压即使用类型的安装包,因此只需将文件解压即可,解压后即可得到Go语言的编译器、标准库以及其他相关工具和文件的源代码。如下:

设置环境变量
安装完Go的开发包后,需要设置如下三个环境变量:
GOROOT的作用
在Go开发包的src目录中是Go标准库的源代码,其中每一个目录对应一个包,包名与目录名相同,比如fmt目录中存放的就是fmt包相关的源代码。如下:

GOROOT的作用:
GOPATH的作用
GOPATH的作用:
PATH的作用
PATH的作用:
Go开发包中的bin目录下的可执行文件如下(不同Go版本可能不同):

go命令提供了编译、构建、运行和测试Go程序的功能,通过go version命令可以查看当前的Go版本。如下:

gofmt命令用于格式化Go源代码,使其符合Go语言规范的格式。如下:

gofmt命令默认只会将格式化后的内容输出,如果需要将格式化后的内容写入文件,需要携带-w选项。如下:

特别注意: Go语言中的左大括号不能单独新起一行,否则会导致编译报错。
Go项目目录结构
Go项目的目录结构没有固定的标准,作为Go初学者,可以使用下面这个简单的目录结构来组织项目。如下:

说明一下:
Hello World程序
本篇博客介绍Golang的一些入门知识,于是我在go_code目录下创建了BasicKnowledge目录,用于存放本篇博客的所有代码,并在BasicKnowledge目录下创建了一个HelloWorld目录,用于编写Hello World程序。目录结构如下:

在HelloWorld目录下创建一个main.go文件,并在文件中编写Hello World代码。如下:
package main
import "fmt"
func main() {
fmt.Printf("Hello Golang")
}
通过go build命令可以对Go程序进行编译,并生成可执行文件。如下:

说明一下:
编译后在bin目录下就会生成可执行文件,执行该文件即可输出Hello World。如下:

此外,也可以通过go run命令直接编译并运行Go程序。如下:

注释
行注释和块注释:
例如下面对Hello World代码进行了简单注释。如下:
package main // 将当前文件声明为main包
import "fmt" //引入fmt包
/*这是主函数*/
func main() {
// 调用fmt包的Printf函数输出Hello World
fmt.Printf("Hello World")
}
说明一下:
变量语法
Go中通过var关键字声明变量,如果待声明的变量的类型相同,则可以同时声明多个变量。如下:
var s string // 声明单个变量 var n1, n2, n3 int // 声明多个同类型变量
如果在声明变量的同时给变量赋值,那么变量的数据类型可以省略,让编译器自行推导。此外,还可以直接以变量名 := 表达式的形式声明变量,变量的类型将根据表达式自动推导。如下:
// 声明单个变量并赋值 var s1 string = "dragon" var s2 = "dragon" s3 := "dragon" // 声明多个同类型变量并赋值 var n1, n2, n3 int = 10, 20, 30 var n4, n5, n6 = 10, 20, 30 n7, n8, n9 := 10, 20, 30
在声明多个变量时,如果给这些变量赋值,那么这些不同类型的变量也可以同时声明。如下:
// 声明多个不同类型变量 var s1, n1 = 10, "dragon" s2, n2 := 10, "dragon"
此外,也可以通过下面这种方式进行多变量声明,这种方式通常用于声明全局变量。如下:
// 多变量声明 var ( s1 string = "dragon" n1 int = 10 s2 = "dragon" // 类型可以省略 n2 = 10 // 类型可以省略 )
注意: Go中不能以变量名 := 表达式的方式声明全局变量。
变量作用域
以下是各种变量对应的作用域:
说明一下:
命名规范
Go语言中的函数名、变量名、类型名、包名、方法名、语句标号、等所有的命名,都遵循如下命名规则:
说明一下:
系统关键字
Go中的系统关键字如下:

系统预定义标识符
Go中的系统预定义标识符如下:

说明一下: 这些预定义标识符包括基础数据类型和系统内建函数等,它们不是关键字,我们可以在定义标识符的时候使用它们,但一般不建议这么做。
通过控制台输出
Go中通常使用fmt包中的Println和Printf函数向控制台输出数据。如下:
package main
import "fmt"
func main() {
// 输出一行数据
fmt.Println("Hello", "Golang") // Hello Golang
// 格式化输出
var name string = "2021dragon"
fmt.Printf("your id is %s\n", name) // your id is 2021dragon
}
说明一下:
通过控制台输入
Go中通常使用fmt包中的Scanln和Scanf函数从控制台读取数据。如下:
package main
import "fmt"
func main() {
// 输入一行数据
var str1 string
fmt.Scanln(&str1)
fmt.Printf("%s\n", str1)
// 格式化输入
var str2 string
fmt.Scanf("%s\n", &str2)
fmt.Printf("%s\n", str2)
}
说明一下:
算术运算符
Go中的算术运算符如下:
| 运算符 | 描述 |
|---|---|
| + | 正号 |
| - | 负号 |
| + | 加 |
| - | 减 |
| * | 乘 |
| / | 除 |
| % | 取模 |
| ++ | 自增 |
| – | 自减 |
| + | 字符串相加 |
使用案例如下:
package main
import "fmt"
func main() {
// 算术运算符
var num1 = +25
var num2 = -10
var num3 = num1 + num2
var num4 = num1 - num2
var num5 = num1 * num2
var num6 = num1 / num2
var num7 = num1 % num2
num1++
num2--
var s = "2021" + "dragon"
fmt.Printf("num1 = %d\n", num1) // 26
fmt.Printf("num2 = %d\n", num2) // -11
fmt.Printf("num3 = %d\n", num3) // 15
fmt.Printf("num4 = %d\n", num4) // 35
fmt.Printf("num5 = %d\n", num5) //-250
fmt.Printf("num6 = %d\n", num6) // -2
fmt.Printf("num7 = %d\n", num7) // 5
fmt.Printf("s = %s\n", s) // 2021dragon
}
注意:
关系运算符
Go中的关系运算符如下:
| 运算符 | 描述 |
|---|---|
| == | 等于 |
| != | 不等于 |
| < | 小于 |
| > | 大于 |
| <= | 小于等于 |
| >= | 大于等于 |
使用案例如下:
package main
import "fmt"
func main() {
// 关系运算符
var num1, num2 = 10, 20
fmt.Println(num1 == num2) // false
fmt.Println(num1 != num2) // true
fmt.Println(num1 < num2) // true
fmt.Println(num1 > num2) // false
fmt.Println(num1 <= num2) // true
fmt.Println(num1 >= num2) // false
}
逻辑运算符
Go中的逻辑运算符如下:
| 运算符 | 描述 |
|---|---|
| && | 逻辑与:如果两边的操作数都为true,则为true,否则为false |
| | | | 逻辑或:如果两边的操作数有一个为true,则为true,否则为false |
| ! | 逻辑非:如果条件为true,则为false,否则为true |
使用案例如下:
package main
import "fmt"
func main() {
// 逻辑运算符
var num1, num2 = 10, 20
fmt.Println(num1 > 0 && num2 > 0) // true
fmt.Println(num1 > 10 || num2 > 10) // true
fmt.Println(!(num1 > num2)) // true
}
注意:
赋值运算符
Go中的赋值运算符如下:
| 运算符 | 描述 |
|---|---|
| = | 直接赋值 |
| += | 相加后再赋值 |
| -= | 相减后再赋值 |
| *= | 相乘后再赋值 |
| /= | 相除后再赋值 |
| %= | 求余后再赋值 |
| <<= | 左移后再赋值 |
| >>= | 右移后再赋值 |
| &= | 按位与后再赋值 |
| |= | 按位或后再赋值 |
| ^= | 按位异或后再赋值 |
使用案例如下:
package main
import "fmt"
func main() {
// 赋值运算符
var num1, num2 = 10, 20
num1 = num2 // num1 = 20, num2 = 20
num1 += 10 // num1 = 30, num2 = 20
num2 -= 10 // num1 = 30, num2 = 10
num1 *= 2 // num1 = 60, num2 = 10
num2 /= 5 // num1 = 60, num2 = 2
num1 %= 8 // num1 = 4, num2 = 2
num1 <<= 1 // num1 = 8, num2 = 2
num2 >>= 1 // num1 = 8, num2 = 1
num1 &= num2 // num1 = 0, num2 = 1
num1 |= 4 // num1 = 4, num2 = 1
num2 ^= num1 // num1 = 4, num2 = 5
fmt.Printf("num1 = %d, num2 = %d\n", num1, num2) // num1 = 4, num2 = 5
}
位运算符
Go中的位运算符如下:
| 运算符 | 描述 |
|---|---|
| & | 按位与:将两个操作数进行按位与操作(同时为1,结果为1,否则为0) |
| | | 按位或:将两个操作数进行按位或操作(有一个为1,结果为1,否则为0) |
| ^ | 按位异或:将两个操作数进行按位异或操作(相同为0,相异为1) |
| << | 左移运算符:将左操作数的二进制序列左移若干位(低位补0,高位丢弃,符号位不变) |
| >> | 右移运算符:将左操作数的二进制序列右移若干位(低位丢弃,高位补符号位的值,符号位不变) |
使用案例如下:
package main
import "fmt"
func main() {
// 位运算符
var num1, num2 = 12, -4
// 00...01100 --> 12的原码、反码、补码:
// 10...00100 --> -4的原码
// 11...11011 --> -4的反码
// 11...11100 --> -4的补码
fmt.Println(num1 & num2) // 00...01100 -> 12
fmt.Println(num1 | num2) // 11...11100 -> -4
fmt.Println(num1 ^ num2) // 11...10000 -> 11...01111 -> 10...10000 -> -16
fmt.Println(num1 << 2) // 48
fmt.Println(num2 >> 2) // 11...11111 -> -1
}
注意:
其他运算符
Go中其他的运算符如下:
| 运算符 | 描述 |
|---|---|
| & | 取地址运算符:返回变量存储的地址 |
| * | 解引用运算符:返回指针指向变量的值 |
使用案例如下:
package main
import "fmt"
func main() {
// 其他运算符
var num = 10
fmt.Printf("num的地址是%p\n", &num) // num的地址是0xc00000e0b8
var ptr = &num
*ptr = 20
fmt.Printf("num = %d\n", num) // 20
}
特别说明: Go语言明确不支持三元运算符。