【教程】Go语言快速学习新手友好备注一、基本概念二、数据类型1.基本类型2.变量定义3.指针类型三、复合类型1.结构体2.数组和切片3.映射三、流程控制1.条件语句2.循环语句3.switch语句四、函数1.函数定义2.defer机制3.方法接收者4.接口5.泛型五、错误处理六、并发六、文件七、网络备注2021/04/08 星期四高中竞赛的时候浅学过一点go语言觉得go是一门很有趣的语言但是由于种种原因一直没有深入学习和使用这里总结一下一、基本概念Go语言是一门静态类型、编译型、自动垃圾回收、原生支持并发的编程语言Go语言程序能够很好的实现跨平台部署。Go语言程序的每个代码文件属于一个包package程序会从main包的main函数开始执行。可以用import引入依赖包与其他语言不同如果引入的包未使用会编译报错。类似的在Go语言中定义的变量、函数如果未使用也会编译报错。二、数据类型1.基本类型与大部分语言相同Go语言有四种基本类型整数、小数、布尔型、字符串Go语言中的整数和小数有更详细的划分整数包括int、int8、int16、int32、int64、unit、uint8、uint16、uint32、uint64小数包括float32、float64。2.变量定义Go语言的变量定义有三种方式varaint10// 标准声明varb20// 类型推导c:30// 短声明最常用Go语言中每种类型都有默认的0值变量声明未赋值即为零值。与大部分语言一样Go语言提供了const用于声明常量constPI3.14如果有多个变量可以简化一定的书写//同类型简化定义vara,b,cint//简化定义并初始化a,b,c:1,2,33.指针类型Go语言的指针很少用于运算主要是对数据的引用*用于解引用用于取地址空指针为nil。Go语言还在语法层面提供了“自动解引用”机制具体的原则为如果有一个值v且可取址可以调用接收指针的方法Go自动取址v如果有一个指针p可以调用接收值的方法Go自动解引用*p。三、复合类型1.结构体Go语言中没有类可以使用结构体struct对数据类型进行封装但是结构体默认是没有名字的匿名想要给结构体命名还需要使用type因此一个常见的结构体体定义为// 常用定义typePeoplestruct{NamestringAgeint}//匿名定义并立即声明对应变量myPeople:struct{NamestringAgeint}{Name:xiaoming,Age:18,}Go语言还在结构体中提供了标签用于简化网络请求代码的编写标签直接附加在结构体字段后面指定字段在序列化或ORM映射时的信息。typeUserstruct{Usernamestringjson:username xml:user_namePasswordstringjson:-// -表示忽略该字段Ageintjson:age,omitempty// omitempty表示如果字段为零值则忽略}2.数组和切片Go语言中的数组是定长数组不可改变数组长度切片是变长数组可以改变数组长度定义时的主要区别是[]中有没有指定长度没必要过度强调名称的不同使用时知道区别即可。a:[3]int{1,2,3}// 数组固定长度为3b:[]int{1,2,3}// 切片不指定长度bappend(b,4)// 扩容元素append返回新切片3.映射映射map是键值对的无序集合在某些语言中可能叫做字典并没有本质上的区别映射中的键只能是基本数据类型映射必须初始化后才能使用未初始化的映射是 nil不能直接写入数据但可以读返回零值varamap[string]int//定义amake(map[string]int)//初始化b:make(map[string]int)//定义并初始化空映射c:map[string]int{//定义并初始化字面值one:1,two:2,}三、流程控制1.条件语句与其他语言一样Go语言的if语句也是用于判断的但是Go还提供了一种携带初始化语句的方式用于简化if语句的书写// 普通写法age:18ifage18{fmt.Println(未成年)}else{fmt.Println(成年人)}// 初始化写法ifage:18;age18{fmt.Println(未成年)}else{fmt.Println(成年人)}2.循环语句与其他语言不同Go语言只有一种循环语句for没有 while和do-while但是Go语言的for语句有多种写法可以用于不同方式的循环// 普通for循环fori:0;i10;i{...}// 类似while循环i:0fori10{...}// 死循环for{...}// 类似python循环nums:[]int{1,2,3}forindex,value:rangenums{...}3.switch语句Go语言中的switch语句与其他语言差异比较大Go语言的switch语句同样有两种写法并且在一个case中可以写多个条件默认只执行匹配项的语句不需要break终止后面其他条件的语句如果想要继续执行下一个条件的语句的内容需要使用fallthrough// 普通switch语句week:3switchweek{case1,2,3,4,5:fmt.Println(工作日)case6,7:fmt.Println(休息日)default:fmt.Println(星期错误)}// Go省略写法year:2021switch{caseyear%4000:fallthroughcaseyear%40year%100!0:fmt.Printf(%d年是闰年\n,year)default:fmt.Printf(%d年不是闰年\n,year)}四、函数1.函数定义Go语言使用func定义函数并且Go语言的函数支持多返回值还可以为返回值命名如果使用了命名返回值可以只使用return返回而不需要携带要返回的值//普通函数定义funcadd(a,bint){...}//多返回值函数定义funcswap(a,bint)(int,int){returnb,a}//多返回值带命名定义funcswap(a,bint)(x,yint){xb yareturn}2.defer机制Go提供了defer语句用于在函数返回前执行操作一般用于释放资源有点类似面向对象语言中类的析构函数如果一个函数中有多条defer语句会按照先进后出的顺序执行funcduelFile(){f:openFile()deferf.Close()}3.方法接收者由于Go语言不是面向对象的语言如果一个函数想要像类的方法一样使用则需要绑定接收者接收者可以是值也可以是指针当方法绑定了接收者就可以访问结构体中的字段了typePeoplestruct{Namestring}// Speak方法绑定接收者(p People)可以用.访问结构体中的字段p是接收者的名字类似其他语言中的this或selffunc(p People)Speak(){// 使用接收者 d 来访问字段fmt.Printf(%s说:你好\n,p.Name)}// 绑定指针接收者可以直接修改字段中的数据func(p*People)SetName(newNamestring){p.NamenewName}4.接口Go语言提供了interface用于声明接口但是与大部分语言不同Go语言的接口是隐式实现的一个结构体只要实现了接口的所有方法就自动实现了该接口。typeAnimalinterface{Speak()}typeDogstruct{}func(d Dog)Speak(){fmt.Println(Woof!)}Go语言中空接口写为 any可以接收任意类型类似于其他语言的Object5.泛型Go语言使用方括号[]声明类型参数如果想定义类型约束可以使用接口限制泛型参数的范围// 接受任意类型funcTest[T any](s T){fmt.Println(s)}// 限定类型typeNumberinterface{int|int8|int16|int32|int64|float64|float32}funcadd[T Number](a,b T){fmt.Println(ab)}五、错误处理Go语言的错误处理和大部分语言不同没有使用try、catch方式而是c语言的返回值判断方式大部分函数的最后一个返回值都是错误值res,err:divide(1,0)iferr!nil{fmt.Println(Error:,err)return}fmt.Println(Result:,res)Go语言中的panic类错误用于不可恢复的严重错误recover用于捕获panic防止程序崩溃。funcmustPanic(){deferfunc(){ifr:recover();r!nil{fmt.Println(panic:,r)}}()panic(严重错误)}六、并发Go语言的并发使用go关键词提供了协程其他语言一般使用多线程/多进程协程是一种很轻量的机制使用也很方便funcsay(sstring){fmt.Println(s)}funcmain(){gosay(World)}六、文件Go语言提供了os包用于处理文件// 简单写文件data:[]byte(Hello, World!)err:os.WriteFile(test.txt,data,0644)// 简单读文件data,err:os.ReadFile(test.txt)fmt.Println(string(data))// 按模式打开文件模式有O_RDONLY只读、O_WRONLY只写、O_RDWR读写、O_CREATE不存在则创建、O_APPEND追加写入、O_TRUNC打开时清空文件file,_:os.OpenFile(test.txt,os.O_RDWR|os.O_CREATE|os.O_APPEND,0644)deferfile.Close()}七、网络Go语言内置了net/http包方便进行网络通信内置了http包启动Web服务和处理网络路由funchandler(w http.ResponseWriter,r*http.Request){fmt.Fprintf(w,Hello, you requested: %s\n,r.URL.Path)}funcmain(){http.HandleFunc(/,handler)http.ListenAndServe(:8080,nil)}