go学习笔记

27 阅读4分钟

学习指导

go学习路线

菜鸟教程

青铜教程:go语言中文文档

入门

安装

golang.google.cn/dl/

image.png

选择pkg,进行点击安装就好,其他方式会报错。

go常用指令介绍

go mod init 项目名称 // 初始化项目,类似npm init

go get -u 三方sdk地址 // 引入三方sdk

go mod tidy // 安装依赖,类似npm i

go run 文件.go // 启动代码,类似node

go build 文件.go // 生成二进制文件

初始化一个项目

go mod init 项目名称
mkdir index.go

index.go内容

package main
import "fmt"
func main() {
    fmt.Println("hello go")
}

启动

go run index.go

go语法

Go 中数组赋值和函数传参都是值复制的。

对于固定语法,声明了元素,但是不需要使用它,可以用 _ 代替,就不会报错了。_是特殊标识符,用来忽略结果。

for index, _ := range "abcdefg" {}

指针

Go 中数组赋值和函数传参都是值复制的。

list := []int{1, 2, 3, 4, 5}
list1 := list
fmt.Printf("list : %p , %v\n", &list, list)
fmt.Printf("list1 : %p , %v\n", &list1, list1)

指针的声明与取值

a := 10
b := &a // &声明
fmt.Printf("b : %p , %v\n", b, *b) // b : 0xc0000120c8 , 10
*b = 20 // *取值
fmt.Printf("a : %p , %v\n", &a, a) // a : 0xc0000120c8 , 20

nil // 空指针

go对于引用类型(slice、map、channel)的变量,需要 声明 + 分配内存空间,需要用到new与make

var a *int // 声明
*a = 100 // 复制
// 会报错,因为没有指针没有内存空间

var a *int // 声明
a = new(int) // 分配内存空间
*a = 100 // 复制
// 等价于
a := new(int)
*a = 100

var b map[string]int // 声明指针
b = make(map[string]int, 10) // 指针赋值
b["sss"] = 1

new与make的区别

  1. 二者都是用来做内存分配的。
  2. make只用于slice、map以及channel的初始化,返回的还是这三个引用类型本身;
  3. 而new用于类型的内存分配,并且内存对应的值为类型零值,返回的是指向类型的指针。

数组与切片

// 声明数组
list := [5]int{1,2,3,4,5}

// 声明切片
listSlice := []int{1,2,3,4,5}
listSlice1 := []int{6}
listSlice2 := make([]int, 5)
// 切片新增元素
listSlice = append(listSlice, 6)
listSlice = append(listSlice, listSlice1...)

区别:

  • 数组长度固定,切片不固定

map

声明map

// make(map[key的类型]value的类型) 这是map
// make([]元素的类型) 这是切片
// make(chan 通道的类型) 这是通道
cMap := make(map[string]int, 10)
cMap["a"] = 1
cMap["b"] = 2

// 查
value, ok := cMap["c"] 
for key, val := range cMap {
        fmt.Println(key, val)
}

// 删除
delete(cMap, "b")

go并发goroutine

go fn1() // 执行并发
go fn2() // 执行并发

使用chan(通道)获取并发的值。


func getVal1(val int, accpet chan int) {
	time.Sleep(1 * time.Second)
	accpet <- val
}
func getVal2(val int, accpet chan int) {
	time.Sleep(2 * time.Second)
	accpet <- val
}
func main() {
	fmt.Println("begin", time.Now().Second()) // 假设是1s
	accpet := make(chan int)
	go getVal1(11, accpet)
	go getVal2(12, accpet)
	a := <-accpet // 获取通道值的过程中,会阻塞主线程 
	fmt.Println(time.Now().Second()) // 执行到这就是2
	b := <-accpet // 获取通道值的过程中,会阻塞主线程
	fmt.Println(time.Now().Second()) // 到这就是3
	fmt.Println(a, b)

}

遍历

string 遍历

for index, charUnicode := range "abcdefg" {}
// index为下标,charUnicode为字符串unicode

map 遍历

cMap := make(map[string]int)
cMap["a"] = 1
cMap["b"] = 2
for key, val := range cMap){}

类型定义和类型别名

type 自定义数据类型 数据类型
type myInt int  // 类型定义
type myInt1 = int // 类型别名

结构体

type 类型名 struct {
    字段名 字段类型
    字段名 字段类型
} 
type Person struct {
    name string
    city string
    year, sex int8
}
var p1 person
p1.name = 'a'
p1.city = 'b'
p1.age = 20
p1.sex = 2

// 或者

var p2 struct {
    name string
    city string
    year, sex int8
}


// 指针类型结构体
var p3 = new(Person)
p3.name = "asd" // go语法糖,等价于 (*p3).name,只存在于结构体指针

// 结构体初始化
p4 := Person {
  name:"asd",
  city:"ccc",
}

// 指针结构体初始化
p5 := &Person {
  name:"asd"
}

构造函数、成员变量、成员方法

// 声明结构体
type Person struct {
	name string
	city string
}

// 声明构造函数
func NewPerson(name string, city string) *Person {
	return &Person{
		name: name,
		city: city,
	}
}

// 声明实例对应方法
func (p Person) GetName() string {
	return p.name
}

func main() {
	p := NewPerson("asd", "ccc")
	fmt.Println(p.GetName())
}

select

select是Go中的一个控制结构,类似于switch语句,用于处理异步IO操作。select会监听case语句中channel的读写操作,当case中channel读写操作为非阻塞状态(即能读写)时,将会触发相应的动作。
select中的case语句必须是一个channel操作

select中的default子句总是可运行的。

如果有多个case都可以运行,select会随机公平地选出一个执行,其他不会执行。

如果没有可运行的case语句,且有default语句,那么就会执行default的动作。

如果没有可运行的case语句,且没有default语句,select将阻塞,直到某个case通信可以运行

func main() {
	a, b, c := make(chan int), make(chan int), make(chan int)
	go func() {
		time.Sleep(1 * time.Second)
		a <- 1
	}()
	go func() {
		time.Sleep(1 * time.Second)
		b <- 2
	}()
	go func() {
		time.Sleep(1 * time.Second)
		c <- 3
	}()
	select {
	case <-a:
		fmt.Println('a')
	case <-b:
		fmt.Println('b')
	case <-c:
		fmt.Println('c')
	}
}

依赖安装慢的解决方法

www.jianshu.com/p/e67acd1c8…

go env -w GO111MODULE=on

g env -w GOPROXY="https://mirrors.aliyun.com/goproxy/,direct"

# 查看配置情况
go env 

image.png

链接mysql数据库