go语言入门练习合集

  1. go牛顿法求平方根
package main

import (
	"fmt"
	"math"
)

func Sqrt(x float64) float64 {
	z := 1.0
	for math.Abs(x - z*z) > 0.000000001 {
		z -= (z*z - x) / (2*z)
	}
	return z
}`在这里插入代码片`

func main() {
	fmt.Println(Sqrt(2))
	fmt.Println(math.Sqrt(2))
}

  1. 切片练习
package main

import "golang.org/x/tour/pic"
import "math"

func Pic(dx, dy int) [][]uint8 {
	ans := make([][]uint8, dy)
	for y := 0; y < dy; y++ {
		row := make([]uint8, dx)
		for x := 0; x < dx; x++ {
			fx := float64(x)
			fy := float64(y)
			row[x] = uint8(math.Pow(fx, fy))
		}
		ans[y] = row
	}
	return ans
}

func main() {
	pic.Show(Pic)
}

  1. map练习
package main

import (
	"golang.org/x/tour/wc"
	"strings"
)

func WordCount(s string) map[string]int {
	words := strings.Fields(s)
	ans := map[string]int{}
	//ans := make(map[string]int)
	for i := range words {
		ans[words[i]]++
	}
	return ans
}

func main() {
	wc.Test(WordCount)
}
  1. closure 求fibonacci
package main

import "fmt"

// 返回一个“返回int的函数”
func fibonacci() func() int {
	a, b := 0, 1
	return func() int {
		c := a
		a = b
		b = a+c
		return c
	}
}

func main() {
	f := fibonacci()
	for i := 0; i < 10; i++ {
		fmt.Println(f())
	}
}

  1. fmt.stringer
package main

import "fmt"

type IPAddr [4]byte

// TODO: 给 IPAddr 添加一个 "String() string" 方法
func (v IPAddr) String() string {
	return fmt.Sprintf("%v.%v.%v.%v",v[0],v[1],v[2],v[3])
}

func main() {
	hosts := map[string]IPAddr{
		"loopback":  {127, 0, 0, 1},
		"googleDNS": {8, 8, 8, 8},
	}
	for name, ip := range hosts {
		fmt.Printf("%v: %v\n", name, ip)
	}
}

  1. Error handling
package main
import (
   "fmt"
   "math"
)

type ErrNegativeSqrt float64

func (e ErrNegativeSqrt) Error() string {
   return fmt.Sprintf("cannot Sqrt negative number: %v", float64(e))
}

func Sqrt(x float64) (float64, error) {
   if x < 0 {
   	return 0, ErrNegativeSqrt(x)	
   } else {
   	return math.Sqrt(x), nil
   }
}

func main() {
   fmt.Println(Sqrt(2))
   fmt.Println(Sqrt(-2))
}
  1. Reader-exercise, ASCII字符’A’的无限流
package main

import "golang.org/x/tour/reader"

type MyReader struct{}

// TODO: 给 MyReader 添加一个 Read([]byte) (int, error) 方法
func (r MyReader) Read(b []byte) (int, error) {
	b[0] = 'A'
	return 1, nil
}

func main() {
	reader.Validate(MyReader{})
}

  1. rot13Reader
package main

import (
	"io"
	"os"
	"strings"
)

type rot13Reader struct {
	r io.Reader
}

func rot13(x byte) byte {
	switch {
		case (x >= 65 && x <= 77) || (x >= 97 && x <= 109):
			x = x + 13
	case (x >= 78 && x <= 90) || (x >= 110 && x <= 122):
			x = x - 13
	}
	return x
}

func (rot rot13Reader) Read (b []byte) (int, error) {
	n, err := rot.r.Read(b)
	for i := 0; i <= n; i++ {
		b[i] = rot13(b[i])
	}
	return n,err
}

func main() {
	s := strings.NewReader("Lbh penpxrq gur pbqr!")
	r := rot13Reader{s}
	io.Copy(os.Stdout, &r)
}

  1. 图像
package main

import "golang.org/x/tour/pic"
import "image"
import "image/color"

type Image struct{
	w int
	h int
	x int
	y int
}

func (im Image) Bounds() image.Rectangle {
	return image.Rect(0, 0, im.w, im.h)	
}

func (im Image) ColorModel() color.Model {
	return color.RGBAModel
}

func (im Image) At (x, y int) color.Color {
	return color.RGBA{uint8(im.x), uint8(im.y), uint8(255), uint8(115)}
}

func main() {
	m := Image{200, 200, 180, 60}
	pic.ShowImage(m)
}

  1. 信道实现等价二叉查找树比较
package main

import "golang.org/x/tour/tree"
import "fmt"

// Walk 步进 tree t 将所有的值从 tree 发送到 channel ch。
func Walk(t *tree.Tree, ch chan int) {
	walk(t, ch)
	close(ch)
}

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

// Same 检测树 t1 和 t2 是否含有相同的值。
func Same(t1, t2 *tree.Tree) bool {
	ch1 := make(chan int)
	ch2 := make(chan int)
	go Walk(t1, ch1)
	go Walk(t2, ch2)
	for i := range ch1 {
		if i != <- ch2 {
			return false
		}
	}
	return true
}

func main() {
	ch := make(chan int)
	go Walk(tree.New(3), ch)
	for i := range ch {
		fmt.Println(i)
	}
	fmt.Println(Same(tree.New(1),tree.New(1)))
	fmt.Println(Same(tree.New(1),tree.New(5)))
}

  1. 爬虫练习
package main

import (
	"fmt"
	"sync"
)

type Fetcher interface {
	// Fetch 返回 URL 的 body 内容,并且将在这个页面上找到的 URL 放到一个 slice 中。
	Fetch(url string) (body string, urls []string, err error)
}

// Crawl 使用 fetcher 从某个 URL 开始递归的爬取页面,直到达到最大深度。
func Crawl(url string, depth int, fetcher Fetcher) {
	// TODO: 并行的抓取 URL。
	// TODO: 不重复抓取页面。
        // 下面并没有实现上面两种情况:
	if depth <= 0 {
		return
	}
	
	//避免重复抓取
	if checkUrl(url) {
		return
	}
	
	//标记已抓取
	markUrlCount(url, 1)
	body, urls, err := fetcher.Fetch(url)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Printf("found: %s %q\n", url, body)
	
	//并行抓取
	ch := make(chan int)
	for _, u := range urls {
		go func(url string) {
			Crawl(url, depth-1, fetcher)
			ch <- 1
		}(u)
	}
	
	//等待抓取完成
	for range urls {
		<-ch
	}
	
	return
}

var urlCounter UrlCounter

func checkUrl(url string) bool {
	urlCounter.mux.Lock()
	defer urlCounter.mux.Unlock()
	_, ok := urlCounter.v[url]
	return ok
}

func markUrlCount(url string, count int) {
	urlCounter.mux.Lock()
	defer urlCounter.mux.Unlock()
	urlCounter.v[url] += count
}

func main() {
	urlCounter = UrlCounter{v: make(map[string]int)}
	Crawl("https://golang.org/", 4, fetcher)
}

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

// fakeFetcher 是返回若干结果的 Fetcher。
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 是填充后的 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/",
		},
	},
}

你可能感兴趣的:(go)