GO基础语法 | 青训营笔记

72 阅读4分钟

为什么选择GO

  1. 高性能、高并发
  2. 语法简单、学习曲线平缓
  3. 丰富的标准库
  4. 完善的工具链
  5. 静态链接
  6. 快速编译,拥有最快的编译速度,一万个微服务编译一分钟
  7. 跨平台
  8. 垃圾回收

为什么ByteDance选择GO

  1. 最初选择python,2014年开始,由于性能问题换成了GO
  2. C++不适合在线web业务
  3. 早期团队非JAVA背景
  4. 性能好
  5. 部署容易,上手简单
  6. 内部RPC和HTTP推广

go 基础语法

GO是强类型语言,如 int,string,float,bool

声明方式:

var a = "initial"
var b,c int =1,2
f:=float32(e)

if语句

//if语句
if 7%2==0{
    fmt.Println("这个是if语句,用于判断7%2是否为0")
}

while循环体(用一个for循环替代)


for{
    fmt.Println("loop")
}

for循环体

//循环
for n:=0;n<5;n++{
    if n%2==0{
        continue
    }
    fmt.Println(n)
}

switch语句

//switch
switch a{
    case 1:

}
//默认只运行一个分支case

! 值得注意的是,GO里面只有一个默认的case会被执行,即不像其他语言一样要写default和break,go是执行完了这个case之后就跳出switch语句了

数组

//数组
var a[5] int

//切片
s:=make([]string,3)//make创建切片
s=s.append(s,"d")//必须把结果赋值给原切片
fmt.Println(s)//[d]

c:=make([]string,len(s))
copy(c,s)

map

//map
m:=make(map[string]int)//第一个是key类型,第二个是value的类型
m["one"]=1
m["two"]=2
fmt.Println(m)//map[one:1 two:2]
fmt.Println(len(m))//2
//map既可以单个单个访问,也可以遍历访问
//读取map
r,ok:=m["unknow"]//ok是这个键的值


range体,用于遍历内置容器

//range
for i,num:=range nums{

}


指针

//指针主要用于对参数修改
package main

import "fmt"

func add2(n int) {
	n += 2//在函数中修改了n,但是不会影响到函数之外的n,也就是说,函数执行完之后,n是多少还是多少
}

func add2ptr(n *int) {
	*n += 2//指针会修改变量本身的值
}

func main() {
	n := 5
	add2(n)
	fmt.Println(n) // 5
	add2ptr(&n)
	fmt.Println(n) // 7
}


结构体

package main

import "fmt"

type user struct {
	name     string
	password string
}

func main() {
	a := user{name: "wang", password: "1024"}
	b := user{"wang", "1024"}
	c := user{name: "wang"}
	c.password = "1024"
	var d user
	d.name = "wang"
	d.password = "1024"

	fmt.Println(a, b, c, d)                 // {wang 1024} {wang 1024} {wang 1024} {wang 1024}
	fmt.Println(checkPassword(a, "haha"))   // false
	fmt.Println(checkPassword2(&a, "haha")) // false
}

func checkPassword(u user, password string) bool {
	return u.password == password
}

func checkPassword2(u *user, password string) bool {
	return u.password == password
}

结构体方法

package main

import "fmt"

type user struct {
	name     string
	password string
}

func (u user) checkPassword(password string) bool {
	return u.password == password
}

func (u *user) resetPassword(password string) {
	u.password = password
}

func main() {
	a := user{name: "wang", password: "1024"}
	a.resetPassword("2048")
	fmt.Println(a.checkPassword("2048")) // true
}

error

package main

import (
	"errors"
	"fmt"
)

type user struct {
	name     string
	password string
}

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")
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(u.name) // wang

	if u, err := findUser([]user{{"wang", "1024"}}, "li"); err != nil {
		fmt.Println(err) // not found
		return
	} else {
		fmt.Println(u.name)
	}
}

这个应该是go的一大亮点了,不需要用到try-catch语句块去处理错误

json

json格式应该是用的最多的了,所以这个重点要记一下

package main

import (
	"encoding/json"
	"fmt"
)

type userInfo struct {
	Name  string
	Age   int `json:"age"`
	Hobby []string
}

func main() {
	a := userInfo{Name: "wang", Age: 18, Hobby: []string{"Golang", "TypeScript"}}
	buf, err := json.Marshal(a)
	if err != nil {
		panic(err)
	}
	fmt.Println(buf)         // [123 34 78 97...]
	fmt.Println(string(buf)) // {"Name":"wang","age":18,"Hobby":["Golang","TypeScript"]}

	buf, err = json.MarshalIndent(a, "", "\t")
	if err != nil {
		panic(err)
	}
	fmt.Println(string(buf))

	var b userInfo
	err = json.Unmarshal(buf, &b)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%#v\n", b) // main.userInfo{Name:"wang", Age:18, Hobby:[]string{"Golang", "TypeScript"}}
}

go 并发

协程的概念:协程是用户态的,轻量级的线程,栈KB级别 线程的概念:内核态,线程跑多个协程,栈MB级别 这也是GO天生适合高并发的原因

示例代码:


func hello(i int) {
 println("Hello goroutine: " + fmt.Sprint(i))

}

func main() {
 for i := 0; i < 5; i++ {
  go func(j int) {
   hello(j)
  }(i)
 }
 time.Sleep(time.Second)

}

go提倡通过通信共享内存,也就是通过channel 而不是通过共享内存通信 channel 具体操作: make(chan 元素类型,[缓冲大小])

  • 无缓冲通道 make(chan int)
  • 有缓冲通道 make(chan int,2)

go的线程主要用于做高并发的使用

go应该是可以作为我替代java的一个选择了,不仅仅是go的语法简单,而且开发效率高,有着python一样的开发速度,同时又有着C++一样的性能,可以作为替代java和python开发后端的一大利器。