GO指南Scroll

Published on with 0 views and 0 comments

  

  1.Go 环境

1# GO
2export GO111MODULE=on
3export GOPROXY=https://goproxy.io
4export GOBIN=$HOME/go/bin
5export PATH=$PATH:$GOPROXY:$GOBIN

  2.包每个程序都是包,包入口为 main 包,包名与导入路径的最后一个目录一致。例如, "math/rand" 包由 package rand

  3.导入 import "package name"import( "packagename""packagename")

  4.导出首字母为大写是导出的函数/变量等

  5.函数可以没有参数或者接收多个参数,返回单个/多个或不返回值

1
2func swap(x int, y int) (int, int) {
3	return y, x
4}
5func swap(x, y int) (int, int) { return y, x }

  6.函数返回值可以被命名

1func swap(x,y int)(a,b int){a = y; b = x}

  7.var 变量可以定义在不同域,并给予初始化值

1package main
2
3var a, b, c bool = true, false, false
4
5func main() {
6	var d, e, f = 1, "hahaha", false
7}

  8.基本类型

1bool,string,int,int8,int16,int32,int64
2uint,uint8,uint16,uint32,uint64,uintptr
3byte // unit8类型
4rune // unit32类型
5float32 float64
6complex64 complex128

  9.0 值 bool = false, int =0 ,string =""

  10.类型转换

1var i int =42;
2var f float64 = float64(i);
3var u unit = unit(f);
4//或者 类型推导
5i:=42
6f:=float64(i)
7u:=uint(f)

  11.常量,常量的定义与变量类似,只不过使用 const 关键字。常量可以是字符、字符串、布尔或数字类型的值。常量不能使用 := 语法定义。

1const Pi = 3.14159
2func main(){
3	fmt.Println(Pi);
4}

  12.循环

 1func for(){
 2sum:=0
 3// 常规
 4for i:=0;i<10;i++ {
 5	sum+=i;
 6}
 7// 前置为空
 8for ;sum<1000;sum++{
 9...
10}
11// 前后置为空
12for ;sum<1000;{
13 sum++;
14}
15
16// for = while
17
18for i<100 {
19 i++;
20}
21
22// 死循环
23
24for{
25
26}
27}

  13.条件判断

1if , else ,switch

  14.defer,函数返回在执行,后进先出

1func main(){
2 defer fmt.Println("World");
3fmt.Println("Hello");
4}

  15.指针儿

1p := 10
2i := &p

  16.结构体,直接访问,间接访问,指针访问

 1package main
 2
 3import (
 4	"fmt"
 5)
 6
 7type Point struct {
 8	X int
 9	Y int
10}
11
12func main() {
13	fmt.Println(Point{12, 13})
14	p := Point{}
15	p.X = 32
16	p.Y = 22
17	fmt.Println(p)
18	pp := &p
19	pp.X = 44
20	pp.Y = 55
21	fmt.Println(p)
22}

  17.数组

1

  18.map

 1package main
 2
 3import "fmt"
 4
 5type Vertex struct {
 6	Lat, Long float64
 7}
 8
 9var m map[string]Vertex
10
11func main() {
12	m = make(map[string]Vertex)
13	m["Bell Labs"] = Vertex{40.111, 50.222}
14	d := map[string]Vertex{
15		"hahaha": Vertex{111.111, 2222.222},
16	}
17	e := map[string]Vertex{
18		"aaa": {111.111, 222.222},
19	}
20	e["hahahahah"] = Vertex{222.222, 333.33}
21	// 检测e是否有元素ok:true/false,有的话z就有值,没有就没值
22	z, ok := e["hahahahah"]
23
24	delete(e, "aaa")
25	fmt.Println(m)
26	fmt.Println(d)
27	fmt.Println(e)
28	fmt.Println(z, ok)
29}

  19.函数,函数即值

 1package main
 2
 3import (
 4	"fmt"
 5	"math"
 6)
 7
 8func main() {
 9	// 内部函数
10	hypot := func(x, y float64) float64 {
11		return math.Sqrt(x*x + y*y)
12	}
13	fmt.Println(hypot(3.12, 444))
14}

  结构体加函数

 1package main
 2
 3import (
 4	"fmt"
 5	"math"
 6)
 7
 8type Vertex struct {
 9	X, Y float64
10}
11
12func (v *Vertex) Abs() float64 {
13	return math.Sqrt(v.X*v.X + v.Y*v.Y)
14}
15func main() {
16	v := Vertex{3, 4}
17	fmt.Println(v.Abs())
18}

  非结构体加函数

 1package main
 2
 3import (
 4	"fmt"
 5	"math"
 6)
 7
 8type MyInt int
 9
10type Vertex struct {
11	X, Y float64
12}
13
14func (v *Vertex) Abs() float64 {
15	return math.Sqrt(v.X*v.X + v.Y*v.Y)
16}
17
18func (i MyInt) add(a int) int {
19	return int(i) + a
20}
21func main() {
22	v := Vertex{3, 4}
23	fmt.Println(v.Abs())
24	i := MyInt(1)
25	i = MyInt(i.add(2))
26	fmt.Println(i)
27}¡

  20.接口,更像是一个约定,没有耦合。。。

 1package main
 2
 3import (
 4	"fmt"
 5	"math"
 6)
 7
 8// Abser有一个Abs函数
 9type Abser interface {
10	Abs() float64
11}
12
13// 定义两个结构
14type MyFloat float64
15type Vertex struct {
16	X, Y float64
17}
18
19// 每个结构都有自己的Abs
20func (f MyFloat) Abs() float64 {
21	if f < 0 {
22		return float64(-f)
23	} else {
24		return float64(f)
25	}
26}
27
28func (v *Vertex) Abs() float64 {
29	return math.Sqrt(v.X*v.X + v.Y*v.Y)
30}
31
32func main() {
33	// a为Abser接口类
34	var a Abser
35	// f和v为有Abs函数的实体
36	f := MyFloat(-math.Sqrt2)
37	v := Vertex{3, 4}
38	// f可以把值给a
39	a = f
40	// a调用Abs
41	fmt.Println(a.Abs())
42	// &v也可以把值给a
43	a = &v
44	// a调用v的Abs
45	fmt.Println(a.Abs())
46
47}

  21.错误

1

  22.Reader

1
 1// 结构体接受一个 io.Reader结构的值
 2type rot13Reader struct {
 3	r io.Reader
 4}
 5
 6// 给结构体扩展一个Read函数,让结构体从 io.Reader读值,转换为自己的值
 7func (reader rot13Reader) Read(b []byte) (int, error) {
 8	n, e := reader.r.Read(b)
 9
10	for i := 0; i < n; i++ {
11		b[i] = rot13(b[i])
12	}
13
14	return n, e
15}
16
17// 转换函数
18
19func rot13(b byte) byte {
20	switch {
21	case ('A' <= b && b <= 'M') || ('a' <= b && b <= 'm'):
22		b = b + 13
23	case ('M' < b && b <= 'Z') || ('m' < b && b <= 'z'):
24		b = b - 13
25	}
26	return b
27}

  23.Http

1

  24.图片
这里我启动了 http 妄图把标签渲染到 html,但是失败了

1

  25.多县城

 1package main
 2
 3import (
 4	"fmt"
 5	"time"
 6)
 7
 8func sum(a []int, c chan int) {
 9	sum := 0
10	for _, v := range a {
11		sum += v
12	}
13	// 将Sum放入管道
14	c <- sum
15}
16
17func say(s string) {
18	for i := 0; i < 5; i++ {
19		time.Sleep(100 * time.Millisecond)
20		fmt.Println(s)
21	}
22}
23
24func fibonacci(n int, c chan int) {
25	x, y := 0, 1
26	for i := 0; i < n; i++ {
27		// 循环10次,放入管道
28		c <- x
29		x, y = y, x+y
30	}
31	// 最后给管道发送close结束
32	close(c)
33}
34
35func main() {
36	// goroutine 开启一个线程
37	go say("World")
38	say("Hello")
39	// 一个数组
40	a := []int{12, 3, 4, 4, 5, 6, 77}
41	// 一个管道
42	c := make(chan int)
43	// 开线程调用函数,传入数组和管道
44	go sum(a[:len(a)/2], c)
45	go sum(a[len(a)/2:], c)
46	// 管道里有两个值,队列,先进先出所以顺序保证
47	// 从管道里拿值
48	x, y := <-c, <-c
49	println(x, y)
50	// 带10个位置的缓冲管道
51	c = make(chan int, 10)
52	// 开线程调函数
53	go fibonacci(cap(c), c)
54	// rage循环会一直循环到close然后结束
55	for j := range c {
56		fmt.Println(j)
57	}
58}
 1package main
 2
 3import "fmt"
 4
 5func fibonacci(c, quit chan int) {
 6	x, y := 0, 1
 7	// 死循环
 8	for {
 9		// 选择
10		select {
11		// 有X,则把x放入c
12		case c <- x:
13			x, y = y, x+y
14		// 如果quit管道能取出值则运行
15		case <-quit:
16			fmt.Println("quit")
17			return
18		}
19	}
20}
21
22func main() {
23	// 声明两个管道
24	c := make(chan int)
25	quit := make(chan int)
26	// 直接开线程跑函数
27	go func() {
28		for i := 0; i < 10; i++ {
29			// 从c管道拿值,此时C管道是没有值的,所以进入线程阻塞状态
30			fmt.Println(<-c)
31		}
32		// 最后将 0 给管道 quit
33		quit <- 0
34	}()
35	// 将两个管道给函数
36	fibonacci(c, quit)
37}
 1package main
 2
 3import (
 4	"fmt"
 5
 6	"golang.org/x/tour/tree"
 7)
 8
 9func main() {
10	wch := make(chan int)
11	go Walk(tree.New(1), wch)
12	for v := 0; v < 10; v++ {
13		fmt.Println(<-wch)
14	}
15	Same(tree.New(1), tree.New(1))
16	Same(tree.New(1), tree.New(2))
17}
18
19type Tree struct {
20	Left  *Tree
21	Value int
22	Right *Tree
23}
24
25func Walk(t *tree.Tree, ch chan int) {
26	if t.Value != 0 {
27		ch <- t.Value
28	}
29	if t.Left != nil {
30		Walk(t.Left, ch)
31	}
32	if t.Right != nil {
33		Walk(t.Right, ch)
34	}
35}
36
37func Same(t1, t2 *tree.Tree) bool {
38	make1 := make(chan int)
39	make2 := make(chan int)
40	go Walk(tree.New(1), make1)
41	go Walk(tree.New(1), make2)
42
43	flag := false
44	for i := 0; i < 10; i++ {
45		flag = (<-make1 == <-make2)
46	}
47	fmt.Println(flag)
48	return flag
49}

  26.加锁

 1package main
 2
 3import (
 4	"fmt"
 5	"sync"
 6	"time"
 7)
 8
 9type SafeCounter struct {
10	v   map[string]int
11	mux sync.Mutex
12}
13
14func (c *SafeCounter) Inc(key string) {
15	c.mux.Lock()
16	c.v[key]++
17	c.mux.Unlock()
18}
19
20func (c *SafeCounter) Value(key string) int {
21	c.mux.Lock()
22	// 因为要返回以后在调用,所以加defer
23	defer c.mux.Unlock()
24	return c.v[key]
25}
26
27func main() {
28	c := SafeCounter{v: make(map[string]int)}
29	for i := 0; i < 1000; i++ {
30		go c.Inc("somekey")
31	}
32	time.Sleep(time.Second)
33	fmt.Println(c.Value("somekey"))
34}

标题:GO指南Scroll
作者:fe
地址:https://blog.eiyouhe.com/articles/2020/01/18/1579329273890.html