Go 语言学习:Go 语言之旅——练习题及参考答案

Go 专栏收录该内容
22 篇文章 0 订阅

官方的 Go 语言之旅 包含了一些习题,初学者应该要能够完成这些练习来巩固学习的知识点。今晚我花了几个小时做了这些习题,以给初学者作参考。这些题目我就懒得翻译了,这里给出了每个题目的中英文链接【中文应该是机器翻译的,尽量看英文】。

题目

1. 循环与函数

英文题目链接
中文题目链接

2. 切片

英文题目链接
中文题目链接

3. 字典

英文题目链接
中文题目链接

4. 斐波那契闭包

英文题目链接
中文题目链接

5. Stringers

英文题目链接
中文题目链接

6. 错误

英文题目链接
中文题目链接

7. Readers

英文题目链接
中文题目链接

8. rot13Reader

英文题目链接
中文题目链接

9. Images

英文题目链接
中文题目链接

10. 相等的二叉树

英文题目链接
中文题目链接

11. web 爬虫

英文题目链接
中文题目链接

参考答案

1. 循环与函数

package main

import (
	"fmt"
	"math"
)

func Sqrt(x float64) float64 {
	z0 := 1.0
	z1 := z0
	for {
		z1 -= (z0*z0 - x) / (2 * z0)
		if math.Abs(z0-z1) < 0.0000001 {
			break
		}
		z0 = z1
	}
	return z1
}

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

2. 切片

package main

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

func Pic(dx, dy int) [][]uint8 {
	s := make([][]uint8, dy)
	for i := range s {
		s[i] = make([]uint8, dx)
	}
	for x := 0; x < dx; x++ {
		for y := 0; y < dy; y++ {
			s[x][y] = uint8((x+y)/2)
		}
	}
	return s
}

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

3. 字典

package main

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

func WordCount(s string) map[string]int {
	m := make(map[string]int)
	for _, word := range strings.Fields(s) {
		m[word] += 1
	}
	return m
}

func main() {
	wc.Test(WordCount)
}

4. 斐波那契闭包

package main

import "fmt"

// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
	a := -1
	b := 1
	return func() int {
	    r := a + b
	    a, b = b, a + b
		return r
		
	}
}

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

5. Stringers

package main

import "fmt"

type IPAddr [4]byte

func (ip IPAddr) String() string {
    return fmt.Sprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[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)
	}
}

6. 错误

package main

import (
	"math"
	"fmt"
)

type ErrNegativeSqrt float64

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

func Sqrt(x float64) (float64, error) {
	if x < 0 {
	    return -1.0, ErrNegativeSqrt(x)
	}
	
	z0 := 1.0
	z1 := z0
	for {
		z1 -= (z0*z0 - x) / (2 * z0)
		if math.Abs(z0-z1) < 0.0000001 {
			break
		}
		z0 = z1
	}
	return z1, nil
}

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

7. Readers

package main

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

type MyReader struct{}

// TODO: Add a Read([]byte) (int, error) method to MyReader.
func (r MyReader) Read(b []byte) (int, error) {
	for i := range b {
		b[i] = 'A'
	}
	
	return len(b), nil
}

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

8. rot13Reader

package main

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

type rot13Reader struct {
	r io.Reader
}

func (reader rot13Reader) Read(b []byte) (int, error) {
	n, err := reader.r.Read(b)
	for i := 0; i < n; i++ {
		switch {
		case b[i] >= 'A' && b[i] < 'N':
			b[i] += 13
		case b[i] >= 'N' && b[i] <= 'Z':
			b[i] -= 13
		case b[i] >= 'a' && b[i] < 'n':
			b[i] += 13
		case b[i] >= 'n' && b[i] <= 'z':
			b[i] -= 13
		}
	}
	return n, err
}

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

9. Images

package main

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

type Image struct {
	w, h int
}

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

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

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

func main() {
	m := Image{100, 100}
	pic.ShowImage(m)
}

10. 相等的二叉树

package main

import "fmt"
import "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) {
	if t == nil {
		return
	}

	Walk(t.Left, ch)
	ch <- t.Value
	Walk(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, 10)
	ch2 := make(chan int, 10)
	go Walk(t1, ch1)
	go Walk(t2, ch2)
	var v1, v2 int
	for i := 0; i < 10; i++ {
		v1 = <-ch1
		v2 = <-ch2
		if v1 != v2 {
			return false
		}
	}
	return true
}

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

11. web 爬虫

package main

import (
	"fmt"
	"sync"
)

// 实现一个可在多个 goroutine 间使用的集合
type Set struct {
	mu sync.Mutex
	v  map[string]bool
}

func (s *Set) Add(key string) {
	s.mu.Lock()
	s.v[key] = true
	s.mu.Unlock()
}

func (s *Set) Find(key string) bool {
	s.mu.Lock()
	defer s.mu.Unlock()
	if _, ok := s.v[key]; !ok {
		return false
	}
	return true
}

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, s *Set, quit chan int) {

	defer func() {
		quit <- 0
	}()

	if s.Find(url) {
		return
	}

	s.Add(url)

	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)

	var chs []chan int
	for _, u := range urls {
		ch := make(chan int, 1)
		go Crawl(u, depth-1, fetcher, s, ch)
		chs = append(chs, ch)
	}

	for _, ch := range chs {
		<-ch
	}

	return
}

func main() {
	quit := make(chan int, 1)
	s := &Set{v: make(map[string]bool)}
	go Crawl("https://golang.org/", 4, fetcher, s, quit)
	<-quit
}

// 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/",
		},
	},
}

  • 0
    点赞
  • 0
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 技术工厂 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值