【go语言圣经】习题答案 第一章

自己写了点gopl的练习题,发个答案大家共勉一下。有问题也请大佬指教。

1.1 1.2 打印命令行参数

//  1.1
func test_1_1() {
	fmt.Println(os.Args[0])
}

// 1.2
func test_1_2() {
	for i, arg := range os.Args {
		fmt.Printf("第%d个参数为%s\n", i, arg)
	}
}

1.4 打印重复出现的某行代码及其出现位置

func countLines(f *os.File, m map[string]map[string]int) {
	text := bufio.NewScanner(f)
	for text.Scan() {
		if m[text.Text()] == nil {
			m[text.Text()] = make(map[string]int)
		}
		m[text.Text()][f.Name()]++
	}
	f.Close()
}

// 1.4 打印重复出现的某行代码及其出现位置
func test_1_4() {
	linesMap := make(map[string]map[string]int)
	if len(os.Args) == 1 {
		countLines(os.Stdin, linesMap)
	} else {
		for _, arg := range os.Args[1:] {
			f, err := os.Open(arg)
			if err != nil {
				fmt.Println("open file failed")
			}
			countLines(f, linesMap)
		}
	}
	//print result
	for line, fileName := range linesMap {
		if len(fileName) > 1 {
			fmt.Printf("context: %s\ntimes: %d\nfiles:", line, len(fileName))
			for k, _ := range fileName {
				fmt.Print(k + " ")
			}
			fmt.Printf("\n\n")
		} else {
			for k, v := range fileName {
				if v > 1 {
					fmt.Printf("%s\ntimes:%d\nfiles:%s\n\n", line, v, k)
				}
			}
		}
	}
}

1.5 替换gif图像颜色

var palette = []color.Color{color.White, color.RGBA{0, 0xff, 0, 0xff}}

const (
	whiteIndex = 0 // first color in palette
	blackIndex = 1 // next color in palette
)

func lissajous(out io.Writer) {
	const (
		cycles  = 5     // number of complete x oscillator revolutions
		res = 0.001 // angular resolution
		size    = 100   // image canvas covers [-size..+size]
		nframes = 64 // number of animation frames
		delay   = 8  // delay between frames in 10ms units
	)
	freq := rand.Float64() * 3.0 // relative frequency of y oscillator
	anim := gif.GIF{LoopCount: nframes}
	phase := 0.0 // phase difference
	for i := 0; i < nframes; i++ {
		rect := image.Rect(0, 0, 2*size+1, 2*size+1)
		img := image.NewPaletted(rect, palette)
		for t := 0.0; t < cycles*2*math.Pi; t += res {
			x := math.Sin(t)
			y := math.Sin(t*freq + phase)
			img.SetColorIndex(size+int(x*float64(size)+0.5), size+int(y*float64(size)+0.5),
				blackIndex)
		}
		phase += 0.1
		anim.Delay = append(anim.Delay, delay)
		anim.Image = append(anim.Image, img)
	}
	gif.EncodeAll(out, &anim) // NOTE: ignoring encoding errors
}

// 1.5 替换gif图像颜色
func test_1_5() {
	// The sequence of images is deterministic unless we seed
	// the pseudo-random number generator using the current time.
	// Thanks to Randall McPherson for pointing out the omission.
	rand.Seed(time.Now().UTC().UnixNano())
	lissajous(os.Stdout)
}

1.7 使用io.Copy代替read方法get网页内容

// 1.7 使用io.Copy代替read方法
func test_1_7() {
	for _, arg := range os.Args[1:] {
		resp, err := http.Get(arg)
		if err != nil {
			fmt.Printf("http get failed, error:%v", err)
			break
		}
		_, err = io.Copy(os.Stdout, resp.Body)
		resp.Body.Close()
		if err != nil {
			fmt.Printf("copy content to stdout failed, error:%v", err)
			break
		}
	}
}

1.8 为请求连接增添HTTPS前缀

// 1.8 为请求连接增添HTTPS前缀
func test_1_8() {
	for _, url := range os.Args[1:] {
		if !strings.HasPrefix(url, "https://") {
			url = "https://" + url
		}
		resp, err := http.Get(url)
		if err != nil {
			fmt.Printf("http get failed, error:%v", err)
			break
		}
		b, err := ioutil.ReadAll(resp.Body)
		resp.Body.Close()
		if err != nil {
			fmt.Printf("read body failed, error:%v", err)
			break
		}
		fmt.Printf("content:%s", b)
		if err != nil {
			fmt.Printf("std out failed, error:%v", err)
			break
		}
	}
}

1.9 获取HTTP返回的状态码

// 1.9 获取HTTP返回的状态码
func test_1_9() {
	for _, url := range os.Args[1:] {
		resp, err := http.Get(url)
		if err != nil {
			fmt.Printf("http get failed, error:%v", err)
			break
		}
		fmt.Printf("status code:%s", resp.Status)
	}
}

func fetch(url string, ch chan<- string) {
	start := time.Now()
	resp, err := http.Get(url)
	if err != nil {
		ch <- fmt.Sprintf("http get failed, error:%v", err)
		return
	}
	n, err := io.Copy(io.Discard, resp.Body)
	resp.Body.Close()
	if err != nil {
		ch <- fmt.Sprintf("io copy failed, error:%v", err)
		return
	}
	ch <- fmt.Sprintf("%.2f		%d		%s", time.Since(start).Seconds(), n, url)
}

1.11 对每个URL执行两遍请求,查看两次时间是否有较大的差别,并且每次获取到的响应内容是否一致

func fetch(url string, ch chan<- string) {
	start := time.Now()
	resp, err := http.Get(url)
	if err != nil {
		ch <- fmt.Sprintf("http get failed, error:%v", err)
		return
	}
	n, err := io.Copy(io.Discard, resp.Body)
	resp.Body.Close()
	if err != nil {
		ch <- fmt.Sprintf("io copy failed, error:%v", err)
		return
	}
	ch <- fmt.Sprintf("%.2f		%d		%s", time.Since(start).Seconds(), n, url)
}

// 1.11 对每个URL执行两遍请求,查看两次时间是否有较大的差别,并且每次获取到的响应内容是否一致
func test_1_11() {
	url := os.Args[1]
	ch := make(chan string)
	start := time.Now()
	go fetch(url, ch)
	go fetch(url, ch)
	for i := 0; i < 2; i++ {
		fmt.Println(<-ch)
	}
	fmt.Printf("%f second past", time.Since(start).Seconds())
}

1.12 修改Lissajour服务,从URL读取变量

func lissajous(out io.Writer, cycles float64, size int) {
	const (
		// cycles  = 5     // number of complete x oscillator revolutions
		res = 0.001 // angular resolution
		// size    = 100   // image canvas covers [-size..+size]
		nframes = 64 // number of animation frames
		delay   = 8  // delay between frames in 10ms units
	)
	freq := rand.Float64() * 3.0 // relative frequency of y oscillator
	anim := gif.GIF{LoopCount: nframes}
	phase := 0.0 // phase difference
	for i := 0; i < nframes; i++ {
		rect := image.Rect(0, 0, 2*size+1, 2*size+1)
		img := image.NewPaletted(rect, palette)
		for t := 0.0; t < cycles*2*math.Pi; t += res {
			x := math.Sin(t)
			y := math.Sin(t*freq + phase)
			img.SetColorIndex(size+int(x*float64(size)+0.5), size+int(y*float64(size)+0.5),
				blackIndex)
		}
		phase += 0.1
		anim.Delay = append(anim.Delay, delay)
		anim.Image = append(anim.Image, img)
	}
	gif.EncodeAll(out, &anim) // NOTE: ignoring encoding errors
}


func handler(w http.ResponseWriter, r *http.Request) {
	err := r.ParseForm()
	if err != nil {
		fmt.Fprintf(w, "request parse failed,error: %v", err)
	}
	cycles, _ := strconv.Atoi(r.Form.Get("cycles"))
	size, _ := strconv.Atoi(r.Form.Get("size"))
	lissajous(w, float64(cycles), size)
}
// 1.12 修改Lissajour服务,从URL读取变量
func test_1_12() {
	http.HandleFunc("/", handler)
	http.ListenAndServe("localhost:9999", nil)
}

Go语言圣经》是一本广受好评的教材,旨在帮助读者系统地学习和掌握Go语言。这本书以简明清晰的方式介绍了Go语言的各种特性、语法和用法,是入门和进阶者的理想选择。 首先,该书提供了对Go语言基础知识的全面介绍。它从简单到复杂地解释了Go语言的基本概念,诸如变量、函数、循环和条件语句等等。通过丰富的例子和练习,读者能够逐步理解和掌握这些概念。 其次,该书详细介绍了Go语言的高级特性和用法。读者可以学习到Go语言的面向对象编程、并发编程、网络编程等关键技术。并发编程是Go语言的一个独特特性,对于提高程序性能和扩展能力非常重要。 此外,该书还包含了对常见问题和陷阱的讲解,帮助读者避免一些常见的错误和陷阱。同时,书中提供了大量的案例和实践项目,读者可以通过实际操作来巩固所学内容。 《Go语言圣经》以其简洁明了的风格和对细节的深入讲解而闻名。无论是作为初学者的入门指南,还是作为有经验的开发者的参考书,这本书都能满足读者的需求。此外,该书的PDF版本能够方便地在线或离线阅读,为读者提供了更加便捷的学习体验。 综上所述,《Go语言圣经》是一本内容丰富、权威性强的优秀教材。它不仅适合Go语言的初学者,也适用于那些想要深入学习和掌握Go语言的开发者。无论是在线阅读还是PDF版本,读者都能够方便地获取和利用这本宝贵的学习资源。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值