资源管理 defer

defer

  • 在defer语句位置处就计算用到的参数值,只是放在在函数返回值之前执行
  • 一个函数中的多个defer是栈的结构,先进后出,位置靠前的defer后执行
func f1() {
	defer fmt.Println(1)
	defer fmt.Println(2)
	fmt.Println(3)
	//即使defer后面有return,panic,也会执行defer
	panic("发生错误")
	fmt.Println(4)
}

func f2() {
	i := 1
	//这个defer语句要输出的值在此处就已确认 1,并不是在函数结束、执行defer时才确认
	defer fmt.Println(i)
	i = 10
}

 
defer常用于确保在函数结束时执行语句,常见的使用场景如下

  • Open/Close 资源、连接的关闭
  • Lock/Unlock 锁的释放
  • PrintHeader/PrintFooter
func write(filePath string, str string) {
	//创建文件,可以使用相对路径、绝对路径,但文件名之前的路径要是已存在的,不然会报错
	file, err := os.Create(filePath)
	if err != nil {
		panic(err)
	}
	//函数结束时关闭文件
	defer file.Close()

	//使用缓冲写入文件
	writer := bufio.NewWriter(file)
	//函数结束时把缓冲区的内容刷出到文件
	defer writer.Flush()

	for i := 0; i < 10; i++ {
		writer.WriteString(str)
	}
}

func main() {
	write("test/1.txt", "xxx\n")
}

 

错误处理


 

panic和recover

panic要慎用,不能随便用

//格式化输出,%c是字符
//fmt.Printf("%d%s%d=%d\n", a, operator, b, a*b)


//panic
//panic(fmt.Sprintf("不支持的运算符:%s", operator))

//支持字符串
//panic("不支持的运算符:" + operator)

//整型int转字符串
//	panic("不合法的分数值:" + strconv.Itoa(score))



panic("发生错误")
//panic(errors.New("xxx错误"))

 

待整理

io

func main() {
	//文件读写

	const filePath = "C:/Users/chy/Desktop/1.txt"

	if content, err := ioutil.ReadFile(filePath);err!=nil {
		fmt.Println(err)
	}else {
		//返回的content是byte[],转换为string输出
		fmt.Printf("%s\n", content)
	}

}

 

http

func Get(url string) string {
	resp, err := http.Get(url)
	if err != nil {
		panic(err)
	}

	result, err := httputil.DumpResponse(
		resp, true)

	resp.Body.Close()

	if err != nil {
		panic(err)
	}

	return string(result)

}

 

web

func main() {
	const dir = "/list/"
	http.HandleFunc(dir,
		func(writer http.ResponseWriter, request *http.Request) {
			path := request.URL.Path[len(dir):]
			file, err := os.Open("E:\\go_path\\src\\go_demo\\http-server\\"+path)
			if err != nil {
				panic(err.Error())
			}
			defer file.Close()

			all, err := ioutil.ReadAll(file)
			if err != nil {
				panic(err)
			}

			writer.Write(all)
		})

	err := http.ListenAndServe(":8888", nil)
	if err != nil {
		panic(err)
	}

}