GO指南Scroll

Updated on with 8 views and 2 comments

1.Go 环境

# GO
export GO111MODULE=on
export GOPROXY=https://goproxy.io
export GOBIN=$HOME/go/bin
export PATH=$PATH:$GOPROXY:$GOBIN

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

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

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

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


func swap(x int, y int) (int, int) {
return y, x
}
func swap(x,y int)(int,int){ return y,x}

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

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

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

package main
var a,b,c bool = true,false,false
func main() {
	var d,e,f = 1,"hahaha",false	
}

8.基本类型

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

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

10.类型转换

var i int =42;
var f float64 = float64(i);
var u unit = unit(f);
//或者 类型推导
i:=42
f:=float64(i)
u:=uint(f)

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

const Pi = 3.14159
func main(){
	fmt.Println(Pi);
}

12.循环

func for(){
sum:=0
// 常规
for i:=0;i<10;i++ {
	sum+=i;
}
// 前置为空
for ;sum<1000;sum++{
...
}
// 前后置为空
for ;sum<1000;{
 sum++;
}

// for = while

for i<100 {
 i++;
}

// 死循环

for{

}
}

13.条件判断

if , else ,switch

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

func main(){
 defer fmt.Println("World");
fmt.Println("Hello");
}

15.指针儿

p:=10;
i:=&p;

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

package main

import (
	"fmt"
)

type Point struct {
	X int
	Y int
}

func main() {
	fmt.Println(Point{12, 13})
	p := Point{}
	p.X = 32
	p.Y = 22
	fmt.Println(p)
	pp := &p
	pp.X = 44
	pp.Y = 55
	fmt.Println(p)
}

17.数组


18.map

package main

import "fmt"

type Vertex struct {
	Lat, Long float64
}

var m map[string]Vertex

func main() {
	m = make(map[string]Vertex)
	m["Bell Labs"] = Vertex{40.111, 50.222}
	d := map[string]Vertex{
		"hahaha": Vertex{111.111, 2222.222},
	}
	e := map[string]Vertex{
		"aaa": {111.111, 222.222},
	}
	e["hahahahah"] = Vertex{222.222, 333.33}
	// 检测e是否有元素ok:true/false,有的话z就有值,没有就没值
	z, ok := e["hahahahah"]

	delete(e, "aaa")
	fmt.Println(m)
	fmt.Println(d)
	fmt.Println(e)
	fmt.Println(z, ok)
}


19.函数,函数即值

package main

import (
	"fmt"
	"math"
)
func main() {
	// 内部函数
	hypot := func(x, y float64) float64 {
		return math.Sqrt(x*x + y*y)
	}
	fmt.Println(hypot(3.12, 444))
}

结构体加函数

package main

import (
	"fmt"
	"math"
)

type Vertex struct {
	X, Y float64
}

func (v *Vertex) Abs() float64 {
	return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
func main() {
	v := Vertex{3, 4}
	fmt.Println(v.Abs())
}

非结构体加函数

package main

import (
	"fmt"
	"math"
)

type MyInt int

type Vertex struct {
	X, Y float64
}

func (v *Vertex) Abs() float64 {
	return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

func (i MyInt) add(a int) int {
	return int(i) + a
}
func main() {
	v := Vertex{3, 4}
	fmt.Println(v.Abs())
	i := MyInt(1)
	i = MyInt(i.add(2))
	fmt.Println(i)
}¡

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

package main

import (
	"fmt"
	"math"
)
// Abser有一个Abs函数
type Abser interface {
	Abs() float64
}
// 定义两个结构
type MyFloat float64
type Vertex struct {
	X, Y float64
}
// 每个结构都有自己的Abs
func (f MyFloat) Abs() float64 {
	if f < 0 {
		return float64(-f)
	} else {
		return float64(f)
	}
}

func (v *Vertex) Abs() float64 {
	return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

func main() {
	// a为Abser接口类
	var a Abser
	// f和v为有Abs函数的实体
	f := MyFloat(-math.Sqrt2)
	v := Vertex{3, 4}
	// f可以把值给a
	a = f
	// a调用Abs
	fmt.Println(a.Abs())
	// &v也可以把值给a
	a = &v
	// a调用v的Abs
	fmt.Println(a.Abs())

}

21.错误


22.Reader


// 结构体接受一个 io.Reader结构的值
type rot13Reader struct {
	r io.Reader
}
// 给结构体扩展一个Read函数,让结构体从 io.Reader读值,转换为自己的值
func (reader rot13Reader) Read(b []byte) (int, error) {
	n, e := reader.r.Read(b)

	for i := 0; i < n; i++ {
		b[i] = rot13(b[i])
	}

	return n, e
}
// 转换函数

func rot13(b byte) byte {
	switch {
	case ('A' <= b && b <= 'M') || ('a' <= b && b <= 'm'):
		b = b + 13
	case ('M' < b && b <= 'Z') || ('m' < b && b <= 'z'):
		b = b - 13
	}
	return b
}

23.Http


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


25.多县城

package main

import (
	"fmt"
	"time"
)

func sum(a []int, c chan int) {
	sum := 0
	for _, v := range a {
		sum += v
	}
	// 将Sum放入管道
	c <- sum
}

func say(s string) {
	for i := 0; i < 5; i++ {
		time.Sleep(100 * time.Millisecond)
		fmt.Println(s)
	}
}

func fibonacci(n int, c chan int) {
	x, y := 0, 1
	for i := 0; i < n; i++ {
		// 循环10次,放入管道
		c <- x
		x, y = y, x+y
	}
	// 最后给管道发送close结束
	close(c)
}

func main() {
	// goroutine 开启一个线程
	go say("World")
	say("Hello")
	// 一个数组
	a := []int{12, 3, 4, 4, 5, 6, 77}
	// 一个管道
	c := make(chan int)
	// 开线程调用函数,传入数组和管道
	go sum(a[:len(a)/2], c)
	go sum(a[len(a)/2:], c)
	// 管道里有两个值,队列,先进先出所以顺序保证
	// 从管道里拿值
	x, y := <-c, <-c
	println(x, y)
	// 带10个位置的缓冲管道
	c = make(chan int, 10)
	// 开线程调函数
	go fibonacci(cap(c), c)
	// rage循环会一直循环到close然后结束
	for j := range c {
		fmt.Println(j)
	}
}

package main

import "fmt"

func fibonacci(c, quit chan int) {
	x, y := 0, 1
	// 死循环
	for {
		// 选择
		select {
		// 有X,则把x放入c
		case c <- x:
			x, y = y, x+y
		// 如果quit管道能取出值则运行
		case <-quit:
			fmt.Println("quit")
			return
		}
	}
}

func main() {
	// 声明两个管道
	c := make(chan int)
	quit := make(chan int)
	// 直接开线程跑函数
	go func() {
		for i := 0; i < 10; i++ {
			// 从c管道拿值,此时C管道是没有值的,所以进入线程阻塞状态
			fmt.Println(<-c)
		}
		// 最后将 0 给管道 quit
		quit <- 0
	}()
	// 将两个管道给函数
	fibonacci(c, quit)
}

package main

import (
	"fmt"

	"golang.org/x/tour/tree"
)

func main() {
	wch := make(chan int)
	go Walk(tree.New(1), wch)
	for v := 0; v < 10; v++ {
		fmt.Println(<-wch)
	}
	Same(tree.New(1), tree.New(1))
	Same(tree.New(1), tree.New(2))
}

type Tree struct {
	Left  *Tree
	Value int
	Right *Tree
}

func Walk(t *tree.Tree, ch chan int) {
	if t.Value != 0 {
		ch <- t.Value
	}
	if t.Left != nil {
		Walk(t.Left, ch)
	}
	if t.Right != nil {
		Walk(t.Right, ch)
	}
}

func Same(t1, t2 *tree.Tree) bool {
	make1 := make(chan int)
	make2 := make(chan int)
	go Walk(tree.New(1), make1)
	go Walk(tree.New(1), make2)

	flag := false
	for i := 0; i < 10; i++ {
		flag = (<-make1 == <-make2)
	}
	fmt.Println(flag)
	return flag
}

26.加锁

package main

import (
	"fmt"
	"sync"
	"time"
)

type SafeCounter struct {
	v   map[string]int
	mux sync.Mutex
}

func (c *SafeCounter) Inc(key string) {
	c.mux.Lock()
	c.v[key]++
	c.mux.Unlock()
}

func (c *SafeCounter) Value(key string) int {
	c.mux.Lock()
	// 因为要返回以后在调用,所以加defer
	defer c.mux.Unlock()
	return c.v[key]
}

func main() {
	c := SafeCounter{v: make(map[string]int)}
	for i := 0; i < 1000; i++ {
		go c.Inc("somekey")
	}
	time.Sleep(time.Second)
	fmt.Println(c.Value("somekey"))
}


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