Go语言
Go语言 简单、高效,具备很强的语言表达能力
支持静态类型安全,同时提供动态语言的特性它还支持自动垃圾回收,能够有效防止内存泄漏并从底层支持协程并发,充分利用计算机的硬件性能Go目前在软件行业发挥着重要作用
不少优秀的开源软件都是基于Go进行开发的包括Docker、 Etcd和Kubernetes等
近几年来Go语言发展比较迅猛
但是总体而言它还是属于新生代语言
鉴于我们课程接下来的实践都是围绕着Go来展开的所以在介绍微服务各个组件的详情之前
非常有必要对Go的语法补充一些前置知识
基础语法
// fileName: simple.gopackage main
import(
"fmt""sync"
)
func input(ch chan string){
defer wg.Done()
defer close(ch)
var input string
fmt.Println("Enter 'EOF' to shut down: ")for {
_, err := fmt.Scanf("%s", &input)if err !=nil{
fmt.Println("Read input err: ", err.Error())break
}
if input == "EOF"{fmt.PrintIn("Bye!")break
break}
ch
}
func output(ch chan string){defer wg.Done()
for value := range ch{
fmt.Println("Your input: ", value)}
}
var wg sync.WaitGroupfunc main(){
ch := make(chan string)wg.Add(2)
go input(ch)
go output(ch)
wg.Wait()
var wg sync.WaitGroupfunc main(){
ch := make(chan string)wg.Add(2)
go input(ch)
go output(ch)
wg.Wait()
fmt.Println("Exit! ")}● 变量声明时,变量类型位于变量名后
● 对于if 和for等语句的子句条件,无须使用“()”包起来
● 语句结束无须使用“;”之类的分隔符,通过换行区分
● “{”必须紧跟在对应语句的后面,不可另起一行
go run命令
go run test.go
go build命令
go build -o-test// -o用于指定生成可执行文件名称
go build test.go
函数声明
func funcName(params)(return params){function body
}函数可以接受0个或者以上参数
在声明参数列表时,需要注意参数名在前、类型在后对于连续类型相同的多个参数,可以省略参数类型在最后一个参数中保留类型即可
Go的函数支持多返回值和命名返回值
但是命名返回值和非命名返回值不能混合使用
func Div(dividend, divisor int)(quotient, remainder int){
quotient = dividend/divisor
remainder = dividend%divisorreturn
}
变量的声明与初始化
var nameTvar name T-expressionvar a = 100name :=expressionvalue,_ := fmt.Println()
指针
指针使得开发人员可以直接操作内存空间能够有效地提升程序的执行性能
但是传统的指针容易带来指针偏移错误、忘记释放内存等问题Go移除了指针的运算能力
并引入了自动垃圾回收机制使得Go中的指针在具备高效的内存访问效率同时
不会出现非法修改越界数据和指针占用内存忘记回收等问题
var name *Tpackage main
import "fmt"
func main(){name:= "aoho"p := &name
fmt.Println("name is", *p)*p = "zhu"
fmt.Println("name is", name)
}
struct
type structName struct{
value1 T1
value2 T2
...
}type Student struct{
StudentlD int64
Name string
Birth string
}package main
import "fmt"
func main(){
s0 := Student{}
//1 Key:Value
s1 := Student{
StudentlD:1,
Name:"s1",
birth:" 19900101"
}
//字段赋值顺序与结构体字段定义顺序一致
s2 := Student{
2,
"s2",
"19900102",
}
//获取指针
s3 := &Student{StudentlD:3,Name:"s3",
birth:"19900103",
}
//获取指针s3 := &Student{StudentID:3,Name:"s3",
birth:"19900103",
}
fmt.Println(s0, s1,s2, s3)
fmt.Println(s0.Name, s1.Name, s2.Name,s3.Name)
}
数据结构
除了掌握基本的语法外
语言的一些基本数据结构也必须要掌握
合理使用数据结构能够带来更高的执行效率
Go中常使用的数据结构有 array(数组)、slice(切片)和map(字典)
array (数组)
var name [size]Tpackage main
import "fmt"
func main(){
var numList1 [3]int
numList1[0] = 0
numList1[1]=1
numList1[2]=2
numList2 :=[3]int{0,1,2};
fmt.Println(numList1, numList2)}
slice(切片)
数组使用时难免会遇到扩容的情况切片作为数组一个连续片段的引用它的大小动态可变
可以简单将切片理解为动态数组切片底层由数组实现
如果切片对应的底层数组不足以容纳新的成员时该切片将会进行扩容:
重新申请一段连续的内存空间作为新数组通常为原有数组的2倍
然后将原有切片的数据复制到新数组中把新的成员添加新的数组中
创建新的切片,并指向新数组最后返回新的切片
如果当前切片对应的数组可以容纳更多的数据添加的操作将在原有数组上进行
这将会覆盖掉原有数组的值
接着创建新的切片,并指向原数组最后返回新的切片
slice := source[begin:end]slice := make([]T, size, cap)package main
import "fmt"
func main() {
arr1 :=[...]int{0,1,2,3]
slice1 := arr1[0:4]
slice2 :=make([]int, 4,4)
for i := 0; i< 4 ;i++{
slice2[i]=i
}
slice3 := append(slice1, 5)
slice4 :=[int]{0,1,2,3}
fmt.Println(slice1, slice2, slice3)}
map(字典)
var name map[keyType]valueTypevar name map[keyType]valueType
name = make(map[keyType]valueType)package main
import "fmt"
func main(){
map1 :=make(map[int]string)map1[1]="01"
map1[2]="02"map1[3] ="03"
map2 :=map[int]string{
1: "O1",
2: "02",
3: "03",
}
fmt.Println(map1[0])
value,ok :=map1[1];if ok{
fmt.Println("1 is", value)
}else {
fmt.Println("1 is not existed! ")}
fmt.Println(map2)
}value,ok := map[key]
流程控制
Go中常用的流程控制语句: for、if-else、switch和defer
for循环
for init;condition;end{
circle body
}package main
import "fmt"
func main(){
sum1 :=0
for i :=0;i<10; i++{sum1 +=i
}
sum2 :=1
for sum2<100{
sum2*=2
sum3:=1
for {
if sum3<100{
sum3*=2
}else{break
}
}
fmt.Println(sum1, sum2, sum3)}
分支循环
if condition1{
branch1
}else if condition2 {
branch2
}else {
branch3
}package main
import (
"fmt""time"
func main() {
nowTime := time.Now()
switch nowTime.Weekday(){
case time.Saturday:
fmt.Println("take a rest")
case time.sunday:
fmt.Println("take a rest")
default:
fmt.Println("you need to work")}
switch {
case nowTime.Weekday() >= time.Monday &&nowTime.Weekday() <=time.Friday:
fmt.Println("you need to work")
default:
fmt.Println("take a rest")}
}
defer延迟执行
package main
import "fmt"
func add(a, b int) int {
return a + b
}
func main(){
a:=1
b :=2
defer
fmt.Println("front result: ", add(a, b))//3func main() {
a:=1
b :=2
defer fmt.Println("front result: ", add(a, b)) // 3a=3
b=4
defer fmt.Println("last result: ", add(a, b)) //7a=5
b=6
fmt.Println(add(a, b)) //11
}
//输出
11
7
3
小结
Go是一门优秀的服务端开发语言。具备语法简单、性能优越、静态类型安全、自动垃圾回收等诸多优点