package main
import (
"fmt"
)
func Sqrt(x float64) float64 {
res := 1.0for 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 []uint8for 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 := 1returnfunc() 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
", name, ip)
}
}
error
package main
import (
"fmt"
)
type ErrNegativeSqrt float64func (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.0for 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'
}
returnlen(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':
fallthroughcase'A' <= v && v <= 'M':
buf[i] = v + 13case'n' <= v && v <= 'z':
fallthroughcase'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 chanint) {
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(chanint)
ch2 := make(chanint)
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 {
returnfalse
}
}
returntrue
}
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 chanstring, end chanbool) {
// TODO: 并行的抓取 URL。// TODO: 不重复抓取页面。// 下面并没有实现上面两种情况:if depth <= 0 {
end <- truereturn
}
crawled.mux.Lock()
if _, ok := crawled.crawled[url]; ok {
crawled.mux.Unlock()
end <- truereturn
}
crawled.crawled[url] = 1
crawled.mux.Unlock()
_, urls, err := fetcher.Fetch(url)
if err != nil {
fmt.Println(err)
end <- truereturn
}
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 <- truereturn
}
type Crawled struct {
crawled map[string]int
mux sync.Mutex
}
func main() {
crawled := Crawled{make(map[string]int), sync.Mutex{}}
out := make(chanstring)
end := make(chanbool)
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/",
},
},
}