1 语言特点
语法类似c语言;不需要引入大量经过优化的库文件。易于上手。高并发高性能。 编译很快。跨平台。有垃圾回收机制。强类型语言。
2 环境搭建
2.1 软件安装
对于以下软件,可以参考多项安装教程。本次只有第一步和第三步为新执行,VSCode已经装过。
- 优先在本机安装Go,本系统为Windows。下载网址:go.dev/
- 安装代码编辑器VSCode,下载网址:code.visualstudio.com/
- 在VSCode中安装Go语言扩展。
2.2 简单案例测试
需要通过实际案例判断环境是否成功搭建。
- 构建新项目地址【随便自定义】;
- 打开VSCode,并打开项目文件夹,我的项目名称为GO-EX。
- 新建main.go,填入hello word测试代码。
package main
import (
"fmt"
)
func main() {
fmt.Println("hello world")
}
- 初始化项目,添加go.mod文件。在VSCode中新建终端【Terminal】,出现项目根目录,执行
go mod init <module_name>。未初始化会报错无法执行。本次执行的指令为go mod init example.com/gotext。 - 在终端输入
go run main.go,启动main.go文件,终端输出hello world,即完成环境搭建。
2.3 函数自主补充
在编写代码过程中发现访问某些包时,函数不会自动通过.获取。因此对这部分内容进行补充。有修改过GOPATH,Go相关内容存放在D:\go下。
- 用户变量和系统变量中Path的添加值都改为 %GOPATH%bin。这一步修改完成后重启VSCode并没有解决问题。
- 在成功install all【导入go需要的所有依赖包】后,发现很多地方报错。因此参考如下链接添加go.work文件,该文件出现后,代码能够自动补充函数。
- 参考链接1:添加go.word文件blog.csdn.net/wsi__/artic…
- 参考链接2:解决install失败问题zhuanlan.zhihu.com/p/387853200…
3 语法
3.1 基础语法
3.1.1 定义变量
定义变量关键字:var,一次可以定义单个或多个变量;
另一种格式:变量值 := 值;该方式自动选择数据类型。
由于Go是强类型语言,定义时必须带上变量值所属类型。【区别于python不带数据类型】
3.1.2 匿名变量
标识符为下划线“_”的变量称为匿名变量。属于标识符,仅作占位使用。
赋值后立刻释放的变量。
3.1.3 常量
使用const关键字进行定义,对于常量不能使用:=
3.1.4 案例代码
package main
import (
"fmt"
)
func getNum()(int,int,int){
return 1,2,3;
}
func main() {
var f int;
e, g := 9,10;
s1 := "absc";
f = 1;
_,b,_ := getNum()
fmt.Println(b,e,f,g,s1);
}
math包能够支持数学计算
3.2 循环判断
3.2.1 if判断
GoLang的判断不需要小括号,但是需要大括号。在判断条件之前可以添加执行语句,需要用分号【;】隔开。
if 判断条件 {}
3.2.2 switch
GoLang的switch更加强大,无需添加break语句自动访问下一个case。
package main
import (
"fmt"
"time"
)
func main() {
t := time.Now()
switch {
case t.Hour() < 12:
fmt.Println("It's before noon")
default:
fmt.Println("It's after noon")
}
}
3.2.3 循环
与其它语言的循环不同,Go不支持while循环,只有for循环。
与if语句相似,for语句不使用小括号,但是使用大括号。
for 循环条件【初始条件;判断条件;操作】{}
上述循环条件有三种情况:
- 不写。永远为真,死循环;
- 只判断,不写初始条件和判断。可以看作while循环;
- 所有条件填写完整。同其他语言的for循环,但是不带括号。
3.2.3 案例
for j := 7; j < 9; j++ {
fmt.Println(j)
}
3.3 函数
3.3.1 函数定义
func [函数名](变量1 类型1, 变量2 类型2,...) (返回值){
// 返回值如果是单个值,上面的括号可以不加
return 返回值1,返回值2,...;
}
函数接收的参数类型相同,可以只写一个类型名。
函数支持同时返回多个值,对于不需要的值,可以采用_作为匿名变量。
3.3.2 defer关键字
defer 函数调用语句【defer后面必须是函数调用】
将defer后面执行的函数推迟到外层函数执行到返回值后再执行。
3.4 数组
3.4.1 数组定义
var 数组名 [n]类型:其中,n代表数组个数。数组大小不可改变【同c语言】 赋值方式:
- 数组名[角标] = value 进行赋值;
- b := [5]int{1, 2, 3, 4, 5}
3.4.2 数组切片
类似python中取list的一部分,Golang通过固定上下界取数组一部分值。
数组名[low:hign]:包括第一个元素,不包括最后一个元素【同python类似】
切片值修改,原值也会修改;切片支持append添加元素。 案例代码
package main
import "fmt"
func main() {
var a [5]int
a[4] = 100
fmt.Println("get:", a[2])
fmt.Println("len:", len(a))
b := [5]int{1, 2, 3, 4, 5}
fmt.Println(b[0:3])
var twoD [2][3]int
for i := 0; i < 2; i++ {
for j := 0; j < 3; j++ {
twoD[i][j] = i + j
}
}
fmt.Println("2d: ", twoD)
str := [4]string{"aa","bb","cc","dd"}
str1 := str[0:2]
str2 := str[0:3]
fmt.Println(str1,str2)
str2[0] = "xxx"
fmt.Println(str,str1,str2)
}
3.4.3 make构造切片
make:内建函数,支持创建切片、动态数组。 len():数组定义时约定的长度;len(str[0,0])=0 cap():数组容量,在内存中的长度,底层长度。len(str[0,0])=5
var a [5]int
a[4] = 100
fmt.Println("len:", len(a[0:0]))
fmt.Println("cap:", cap(a[0:0]))
######################
结果输出:
len: 0
cap: 5
make构造切片:变量名 := make([]类型, lenth) 【lenth就是切片长度】。make会分配一个元素为0的数组并返回一个引用了它的切片。
如果想要设置容量:变量名 := make([]类型, lenth, cap)
make支持自定义切片大小。cap指的是在内存中分配的空间大小。
package main
import "fmt"
func main() {
s := make([]string, 3)
s[0] = "a"
s[1] = "b"
s[2] = "c"
fmt.Println("get:", s[2])
fmt.Println("len:", len(s))
s = append(s, "d")
s = append(s, "e", "f")
fmt.Println(s)
c := make([]string, len(s))
copy(c, s)
fmt.Println(c)
good := []string{"g", "o", "o", "d"}
fmt.Println(good) // [g o o d]
}
3.4.4 map
map同样可以使用make构建。变量名 := make(map[string]int)【其中,中括号内的类型代表key值类型,中括号后的类型代表value的类型】
map支持通过range遍历
package main
import "fmt"
func main() {
m := make(map[string]int)
m["one"] = 1
m["two"] = 2
fmt.Println(m) // map[one:1 two:2]
fmt.Println(len(m)) // 2
fmt.Println(m["one"]) // 1
fmt.Println(m["unknow"]) // 0
delete(m, "one")
m2 := map[string]int{"one": 1, "two": 2}
var m3 = map[string]int{"one": 1, "two": 2}
fmt.Println(m2, m3)
}
3.4.5 range
用来遍历,和for联用
package main
import "fmt"
func main() {
nums := []int{2, 3, 4}
sum := 0
for i, num := range nums {
sum += num
fmt.Println("index:", i, "num:", num)
}
fmt.Println(sum)
m := map[string]string{"a": "A", "b": "B"}
for k, v := range m {
fmt.Println(k, v)
}
for k := range m {
fmt.Println("key", k)
}
}
3.5 指针与结构体
3.5.1 指针
*取值;&取地址。
定义方式:在函数中定义func demo(n *int)
3.5.2 结构体
定义结构:
type 【结构名】 struct {
【结构体参数1】 参数类型1
【结构体参数2】 参数类型2
}
结构体执行函数时,可以结合指针使用。
func checkPassword2(u *user, password string) bool {
return u.password == password
}
4 库
4.1 errors
可以在函数返回值中添加error,即函数可能出现错误。支持直接使用if-else对error进行操作。
package main
import (
"errors"
"fmt"
)
type user struct {
name string
password string
}
//函数中添加error返回值
func findUser(users []user, name string) (v *user, err error) {
for _, u := range users {
if u.name == name {
return &u, nil
}
}
return nil, errors.New("not found")
}
func main() {
u, err := findUser([]user{{"wang", "1024"}}, "wang")
//如果调用函数获取到error不为空,输出error
if err != nil {
fmt.Println(err)
return
}
fmt.Println(u.name)
if u, err := findUser([]user{{"wang", "1024"}}, "li"); err != nil {
fmt.Println(err)
return
} else {
fmt.Println(u.name)
}
}
4.2 strings
针对字符串相关操作,包括元素包含判断【strings.Contains()】;字符计算【strings.Count()】;strings.Split();strings.Index()等函数。
4.3 fmt
负责输出的包。
%v支持任意类型输出。%+v、%#v支持更多内容显示。支持浮点数以固定小数位数完成输出【fmt.Printf("%.2f\n",f)】
4.4 json
import包名:encoding/json 构建Json格式的结构名称需要大写第一个字母【大写字母开头】,可以自定义输出形式。【有结构体类似】
type userInfo struct {
Name string
Age int `json:"age"`
Hobby []string
}
json中包含序列化、反序列化、拷贝等多种函数。
4.5 time
time.Now():获取当前时间; 支持Seconds();Year();Month()等函数; t.Format("2006-01-02 15:04:05")【这个时间格式好像是固定的,用于格式转换】。
4.6 strconv
实现进制转换
strconv.ParseFloat("1.234", 64)
4.7 os
os库主要还是涉及系统层面的操作,比如环境变量,cmd/shell指令等内容。