golang官方指导练习(go tour exercise)

本文是golang官方练习的pass代码,使用了中文版的tour

循环与函数

package main

import (
    "fmt"
)

func Sqrt(x float64) float64 {
    res := 1.0
    for i := 0; i < 10; i++ {
        res = res - (res * res - x) / 2 / res
    }
    return res
}

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

slice

package main

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

func Pic(dx, dy int) [][]uint8 {
    var pic [][]uint8;
    for i := 0; i < dy; i++ {
        var one_line []uint8
        for j := 0; j < dx; j++ {
            one_line = append(one_line, (uint8)(i & j))
        }
        pic = append(pic, one_line)
    }
    return pic
}

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

map

package main

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

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

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

斐波纳契闭包

package main

import "fmt"

// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
    one := 0
    two := 1

    return func() int { 
        result := one
        one = two
        two = result + two
        return result
    }
}

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

stringer

package main

import "fmt"

type IPAddr [4]byte

// TODO: Add a "String() string" method to IPAddr.

func (IP IPAddr) String() string {
    return fmt.Sprintf("%v.%v.%v.%v", 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)
    }
}

error

package main

import (
    "fmt"
)

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)
    }
    res := 1.0
    for i := 0; i < 10; i++ {
        res = res - (res * res - x) / 2 / res
    }
    return res, nil
}

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

Reader

package main

import "github.com/Go-zh/tour/reader"

type MyReader struct{}

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

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

rot13Reader

package main

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

type rot13Reader struct {
    r io.Reader
}

func (self rot13Reader) Read(buf []byte) (int, error) {
    length, err := self.r.Read(buf)
    if err != nil {
        return length, err
    }

    for i := 0; i < length; i++ {
        v := buf[i]
        switch {
        case 'a' <= v && v <= 'm':
            fallthrough
        case 'A' <= v && v <= 'M':
            buf[i] = v + 13
        case 'n' <= v && v <= 'z':
            fallthrough
        case 'N' <= v && v <= 'Z':
            buf[i] = v - 13
        }
    }
    return length, nil
}

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

image

package main

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

type Image struct{
    w int
    h int

}

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

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

func (self Image) At(x, y int) color.Color {
    r := (uint8)((float64)(x) / (float64)(self.w) * 255.0)
    g := (uint8)((float64)(y) / (float64)(self.h) * 255.0)
    b := (uint8)((float64)(x * y) / (float64)(self.w * self.h) * 255.0)
    return color.RGBA{r, g, b, 255}
}

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

等价二叉树

package main

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

// Walk 步进 tree t 将所有的值从 tree 发送到 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 检测树 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 := 0; i < 10; i++ {
        x, y := <-ch1, <-ch2
        fmt.Println(x, y)
        if x != y {
            return false
        }
    }
    return true

}

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

Web 爬虫

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, crawled Crawled, out chan string, end chan bool) {
    // TODO: 并行的抓取 URL。
    // TODO: 不重复抓取页面。
        // 下面并没有实现上面两种情况:
    if depth <= 0 {
        end <- true
        return
    }

    crawled.mux.Lock()
    if _, ok := crawled.crawled[url]; ok {
        crawled.mux.Unlock()
        end <- true
        return
    }

    crawled.crawled[url] = 1
    crawled.mux.Unlock()

    _, urls, err := fetcher.Fetch(url)
    if err != nil {
        fmt.Println(err)
        end <- true
        return
    }

    out <- url
    //fmt.Println("found: ", url, body)
    for _, u := range urls {
        go Crawl(u, depth-1, fetcher, crawled, out, end)
    }

    for i := 0; i < len(urls); i++ {
        <-end
    }

    end <- true
    return
}

type Crawled struct {
    crawled map[string]int
    mux sync.Mutex
}
func main() {
    crawled := Crawled{make(map[string]int), sync.Mutex{}}
    out := make(chan string)
    end := make(chan bool)
    go Crawl("http://golang.org/", 4, fetcher, crawled, out, end)

    for {
        select {
        case url := <-out:
            fmt.Println("found: ", url)
        case <-end:
            return
        }
    }
}

// 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{
    "http://golang.org/": &fakeResult{
        "The Go Programming Language",
        []string{
            "http://golang.org/pkg/",
            "http://golang.org/cmd/",
        },
    },
    "http://golang.org/pkg/": &fakeResult{
        "Packages",
        []string{
            "http://golang.org/",
            "http://golang.org/cmd/",
            "http://golang.org/pkg/fmt/",
            "http://golang.org/pkg/os/",
        },
    },
    "http://golang.org/pkg/fmt/": &fakeResult{
        "Package fmt",
        []string{
            "http://golang.org/",
            "http://golang.org/pkg/",
        },
    },
    "http://golang.org/pkg/os/": &fakeResult{
        "Package os",
        []string{
            "http://golang.org/",
            "http://golang.org/pkg/",
        },
    },
}

你可能感兴趣的:(golang)