自己写了点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)
}