go-tour练习解答

简介:

go-tour对于想学习golang的人来说是一个很好的教程。

首先go-tour是有web版本,但是需要FQ。如果不能FQ的,也可以在google code上自己下载go-tour源码,go build,run一下,在自己的机器上就可以跑这个教程了。

提醒下,如果是后者,这篇文章中的程序对应的import包就需要进行相应修改了。

下面给出我的go-tour中的Exercise的解答(在web上已经测试通过)

Exercise: Loops and Functions

第一个循环10次:

复制代码
package main
import (
     "fmt"
)

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

func main() {
     fmt.Println(Sqrt(2))
}
复制代码

第二次无限接近:

复制代码
package main

import (
     "fmt"
     "math"
)

func Sqrt(x float64) float64 {
     z := float64(1)

     for {
          y := z - (z*z - x) / (2 * z)
          if math.Abs(y - z) < 1e-10 {
               return y
          }
          z = y;
     }
     return z
}



func main() {
     fmt.Println(Sqrt(2))
     fmt.Println(math.Sqrt(2))
}
复制代码

Exercise: Maps

复制代码
package main

import (
     "tour/wc"
     "strings"
)

func WordCount(s string) map[string]int {
     ret := make(map[string]int)

     arr := strings.Fields(s)
     for _, val := range arr {
          ret[val]++
     }
     return ret
}

func main() {
     wc.Test(WordCount)
}
复制代码

Exercise: Slices

复制代码
package main

import "tour/pic"

func Pic(dx, dy int) [][]uint8 {
     ret := make([][]uint8, dy)
     for i:=0; i<dy; i++ {
          ret[i] = make([]uint8, dx)
          for j:=0; j<dx; j++ {
               ret[i][j] = uint8(i*j)
          }
     }
     return ret
}

func main() {
     pic.Show(Pic)
}
复制代码

Exercise: Fibonacci closure

复制代码
package main

import "fmt"

// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
     sum1 := 0
     sum2 := 1
     return func() int{
          out := sum1 + sum2
          sum1 = sum2
          sum2 = out
          return out
         
     }
}

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

Advanced Exercise: Complex cube roots

复制代码
package main

import (
     "fmt"
     "math/cmplx"
     )

func Cbrt(x complex128) complex128 {
     z := complex128(1)
     for {
          if y := z-(cmplx.Pow(z,3) - x)/(3 * z * z); cmplx.Abs(y - z) < 1e-10 {
               return y
          } else {
               z = y
          }
     }
     return z
}

func main() {
     fmt.Println(Cbrt(2))
}
复制代码

Exercise: Errors

复制代码
package main

import (
     "fmt"
     "math"
)

type ErrNegativeSqrt float64

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

func Sqrt(f float64) (float64, error) {
     if f < 0 {
          return 0, ErrNegativeSqrt(f)
     }
    
     z := float64(1)
     for {
          y := z - (z*z-f)/(2*z)
          if math.Abs(y-z) < 1e-10 {
               return y, nil
          }
          z = y
     }
     return z, nil
}

func main() {
     fmt.Println(Sqrt(2))
     fmt.Println(Sqrt(-2))
}
复制代码

Exercise: Images

复制代码
package main

import (
     "image"
     "tour/pic"
     "image/color"
)

type Image struct{
     W int
     H int
}

func(self Image) Bounds() image.Rectangle {
     return image.Rect(0, 0, self.W, self.H)
}

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

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

func main() {
     m := Image{W:100, H:100}
     pic.ShowImage(m)
}
复制代码

Exercise: Rot13 Reader

复制代码
package main

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

type rot13Reader struct {
     r io.Reader
}

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


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

Exercise: Equivalent Binary Trees

复制代码
package main

import (
     "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)
     ch2 := make(chan int)
     go func() {
          Walk(t1, ch1)
          ch1 <- 0
     }()
    
     go func() {
          Walk(t2, ch2)
          ch2 <- 0
     }()
    
     for {
          t1 := <-ch1
          t2 := <-ch2
          if t1 == 0 && t2 == 0 {
               return true;
          }
         
          if t1 == t2 {
               continue;
          } else {
               return false;
          }
     }
     return true
}

func main() {
     ch := make(chan int)
     go func() {
          Walk(tree.New(1), ch)
          ch <- 0
     }()
    
     for {
          t := <-ch
          if t == 0 {
               break;
          }
          println(t)
     }
    
     println(Same(tree.New(1), tree.New(2)))
}
复制代码

Exercise: Web Crawler

复制代码
package main

import (
     "fmt"
     "sync"
)

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, out chan string, end chan bool) {
     if depth <= 0 {
          end <- true
          return
     }

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

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

     out <- fmt.Sprintf("found: %s %q\n", url, body)
     subEnd := make(chan bool)
     for _, u := range urls {
          go Crawl(u, depth-1, fetcher, out, subEnd)
     }

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

     end <- true
}

var crawled = make(map[string]bool)
var crawledMutex sync.Mutex

func main() {
     out := make(chan string)
     end := make(chan bool)

     go Crawl("http://golang.org/", 4, fetcher, out, end)
     for {
          select {
          case t := <- out:
               fmt.Print(t)
          case <- end:
               return
          }
     }
}


// 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{
     "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/",
          },
     },
}
复制代码
目录
相关文章
|
JavaScript Go 前端开发
|
26天前
|
存储 JSON 监控
Viper,一个Go语言配置管理神器!
Viper 是一个功能强大的 Go 语言配置管理库,支持从多种来源读取配置,包括文件、环境变量、远程配置中心等。本文详细介绍了 Viper 的核心特性和使用方法,包括从本地 YAML 文件和 Consul 远程配置中心读取配置的示例。Viper 的多来源配置、动态配置和轻松集成特性使其成为管理复杂应用配置的理想选择。
41 2
|
24天前
|
Go 索引
go语言中的循环语句
【11月更文挑战第4天】
26 2
|
24天前
|
Go C++
go语言中的条件语句
【11月更文挑战第4天】
34 2
|
10天前
|
存储 Go 索引
go语言使用for循环遍历
go语言使用for循环遍历
24 7
|
10天前
|
开发框架 Go 计算机视觉
纯Go语言开发人脸检测、瞳孔/眼睛定位与面部特征检测插件-助力GoFly快速开发框架
开发纯go插件的原因是因为目前 Go 生态系统中几乎所有现有的人脸检测解决方案都是纯粹绑定到一些 C/C++ 库,如 OpenCV 或 dlib,但通过 cgo 调用 C 程序会引入巨大的延迟,并在性能方面产生显著的权衡。此外,在许多情况下,在各种平台上安装 OpenCV 是很麻烦的。使用纯Go开发的插件不仅在开发时方便,在项目部署和项目维护也能省很多时间精力。
|
13天前
|
存储 Go
go语言 遍历映射(map)
go语言 遍历映射(map)
26 2
|
14天前
|
Go 调度 开发者
Go语言中的并发编程:深入理解goroutines和channels####
本文旨在探讨Go语言中并发编程的核心概念——goroutines和channels。通过分析它们的工作原理、使用场景以及最佳实践,帮助开发者更好地理解和运用这两种强大的工具来构建高效、可扩展的应用程序。文章还将涵盖一些常见的陷阱和解决方案,以确保在实际应用中能够避免潜在的问题。 ####
|
14天前
|
测试技术 Go 索引
go语言使用 range 关键字遍历
go语言使用 range 关键字遍历
17 3
|
14天前
|
测试技术 Go 索引
go语言通过 for 循环遍历
go语言通过 for 循环遍历
24 3