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

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

第一章练习题答案

    • 1.1 1.2 打印命令行参数
    • 1.4 打印重复出现的某行代码及其出现位置
    • 1.5 替换gif图像颜色
    • 1.7 使用io.Copy代替read方法get网页内容
    • 1.8 为请求连接增添HTTPS前缀
    • 1.9 获取HTTP返回的状态码
    • 1.11 对每个URL执行两遍请求,查看两次时间是否有较大的差别,并且每次获取到的响应内容是否一致
    • 1.12 修改Lissajour服务,从URL读取变量

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)