Go Go Go

安装

ubuntu

在官网下载源码go

这个下载地址被墙了,有点尴尬

windows

下载go:https://golang.org/doc/install

安装相关vscode相关插件: 需要设置代理

go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.io,direct

basic

export names: 所有需要导出的变量名均以大写开头

函数定义:变量名在前,类型在后。如果连续多个参数类型相同,可以只写一次

可以有多个返回值 返回值也可以直接定义变量名,此时return的时候不需要指定返回对象了

func add(x int, y int) int {
	return x + y
}

go 中只有for循环,不需要写(),但一定要写{}

go 如果只写一个表达式,则等同于while

如果啥都不写,则是一个死循环

sum := 0
for i := 0; i < 10; i++ {
    sum += i
}

for sum < 1000 {
    sum += sum
}

for {
}

go if 语句不需要(),必须有{}

if 语句可以定义临时表达式

if value = func(); value >10{
}

go 的switch语句自带break

defer 定义了一个在函数返回后执行的语句

如果定义了多个defer语句,那么通过栈的方式,last in first out

go 的指针可以直接通过.访问struct的成员

数组

var a[10] int

slices:不存数据,是array区间的引用

slices 的 len和 cap

nil slices len = 0, cap = 0

用make创建slice,创建指定长数组

a := make([]int, 5)  // len(a)=5
b := make([]int, 0, 5) // len(b)=0, cap(b)=5

b = b[:cap(b)] // len(b)=5, cap(b)=5
b = b[1:]      // len(b)=4, cap(b)=4

append 往slice中添加元素

range index ,value

pow := make([]int, 10)
for i := range pow {
    pow[i] = 1 << uint(i) // == 2**i
}

go 的map
m = make(map[string]Vertex)

map插入、删除、访问、判断键值是否存在

m := make(map[string]int)

m["Answer"] = 42
fmt.Println("The value:", m["Answer"])

m["Answer"] = 48
fmt.Println("The value:", m["Answer"])

delete(m, "Answer")
fmt.Println("The value:", m["Answer"])

v, ok := m["Answer"]
fmt.Println("The value:", v, "Present?", ok)go

函数作为参数

func compute(fn func(float64, float64) float64) float64 {
	return fn(3, 4)
}

func main() {
	hypot := func(x, y float64) float64 {
		return math.Sqrt(x*x + y*y)
	}
	fmt.Println(hypot(5, 12))

	fmt.Println(compute(hypot))
	fmt.Println(compute(math.Pow))
}

函数闭包

func adder() func(int) int {
	sum := 0
	return func(x int) int {
		sum += x
		return sum
	}
}

func main() {
	pos, neg := adder(), adder()
	for i := 0; i < 10; i++ {
		fmt.Println(
			pos(i),
			neg(-2*i),
		)
	}
}

method

method 是function的一种

go 中没有类,但可以通过定义receiver method 实现类似成员函数的东西

pointer reciver: 会改变成员变量的值


type Vertex struct {
	X, Y float64
}

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

func (v *Vertex) Scale(f float64) {
	v.X = v.X * f
	v.Y = v.Y * f
}

func main() {
	v := Vertex{3, 4}
	fmt.Println(v.Abs())
}


Interfaces

An interface type is defined as a set of method signatures.

对象可隐式类型转换为Interfaces

访问nil interface没有意义,会出错

empty interface

Stringer , Error

Reader

channels

chan<- int表示只发送的channel,不接收
<-chan int 表示只接收不发送的channel

不能close只接收的channel

  • cap() 查看容量 capacity
  • len() 获得长度

测试覆盖率

  • go tool cover

Goroutines

Buffered Channels

当channel的buffer满了,会产生阻塞

range and close 判断一个channel是否已关闭

change 的 for range:循环取值,直到channel 关闭

func fibonacci(n int, c chan int) {
	x, y := 0, 1
	for i := 0; i < n; i++ {
		c <- x
		x, y = y, x+y
	}
	close(c)
}

func main() {
	c := make(chan int, 10)
	go fibonacci(cap(c), c)
	for i := range c {
		fmt.Println(i)
	}
}

select 语句监听多个 channel,阻塞直到某一个channel有数据,并执行那个channel

如果同时有多个channel,则随机执行一个

default select 如果select没有满足条件的,那么可以执行default

sync.Mutex Lock Unlock

sync.WaitGroup

package main

import (
	"fmt"

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

// Walk walks the tree t sending all values
// from the tree to the channel ch.
func Walk(t *tree.Tree, ch chan int) {
	WalkAux(t, ch)
	close(ch)
}

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

// Same determines whether the trees
// t1 and t2 contain the same values.
func Same(t1, t2 *tree.Tree) bool {
	ch1 := make(chan int)
	ch2 := make(chan int)
	go Walk(t1, ch1)
	go Walk(t2, ch2)
	for {
		v1, s1 := <-ch1
		v2, s2 := <-ch2
		if s1 != s2 || v1 != v2 {
			return false
		}
		if s1 == false {
			break
		}

	}
	return true
}

func main() {
	fmt.Println(Same(tree.New(1), tree.New(2)))
	fmt.Println(Same(tree.New(1), tree.New(1)))
	fmt.Println(Same(tree.New(2), tree.New(2)))
}
package main

import (
    "fmt"
    "sync"
)

type FetchMap struct{
    Mu sync.Mutex
    Map map[string] int
}
var mymap = FetchMap{Map : make( map[string] int)}

type Fetcher interface {
    // Fetch returns the body of URL and
    // a slice of URLs found on that page.
    Fetch(url string) (body string, urls []string, err error)
}

// Crawl uses fetcher to recursively crawl
// pages starting with url, to a maximum of depth.
func Crawl(url string, depth int, fetcher Fetcher) {
    mymap.Mu.Lock()
    _ , ok := mymap.Map[url]
    mymap.Map[url] = 1
    mymap.Mu.Unlock()
    if ok {
        return
    }
    // TODO: Fetch URLs in parallel.
    // TODO: Don't fetch the same URL twice.
    // This implementation doesn't do either:

    if depth <= 0 {
        return
    }
    body, urls, err := fetcher.Fetch(url)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Printf("found: %s %q\n", url, body)
    wg := sync.WaitGroup{}
    wg.Add(len(urls))
    for _, u := range urls {
        go func (u string){
            defer wg.Done()
            Crawl(u, depth-1, fetcher)
        }(u)
    }
    wg.Wait()
    return
}

func main() {
    Crawl("https://golang.org/", 4, fetcher)
}

// fakeFetcher is Fetcher that returns canned results.
type fakeFetcher map[string]*fakeResult

type fakeResult struct {
    body string
    urls []string
}

func (f fakeFetcher) Fetch(url string) (string, []string, error) {
    if res, ok := f[url]; ok {
        return res.body, res.urls, nil
    }
    return "", nil, fmt.Errorf("not found: %s", url)
}

// fetcher is a populated fakeFetcher.
var fetcher = fakeFetcher{
    "https://golang.org/": &fakeResult{
        "The Go Programming Language",
        []string{
            "https://golang.org/pkg/",
            "https://golang.org/cmd/",
        },
    },
    "https://golang.org/pkg/": &fakeResult{
        "Packages",
        []string{
            "https://golang.org/",
            "https://golang.org/cmd/",
            "https://golang.org/pkg/fmt/",
            "https://golang.org/pkg/os/",
        },
    },
    "https://golang.org/pkg/fmt/": &fakeResult{
        "Package fmt",
        []string{
            "https://golang.org/",
            "https://golang.org/pkg/",
        },
    },
    "https://golang.org/pkg/os/": &fakeResult{
        "Package os",
        []string{
            "https://golang.org/",
            "https://golang.org/pkg/",
        },
    },
}

© 皖ICP备20011981号