Go 语言入门指南:高质量编程| 青训营

104 阅读3分钟

本篇文章,将讲解以下几点:如何编写更简洁清晰的代码、常用GO语言程序优化手段、熟悉GO程序性能分析工具、了解工程中性能优化的原则和流程。

首先高质量代码,指的是编写的代码能够达到正确可靠、简洁清晰的目标。同时还需要满足完备考虑各种边界条件、异常情况处理稳定性保证、易读易维护的条件。 实际应用场景干变万化,各种语言的特性和语法各不相同,但是高质量编程循的原则是相通的。

Go语言开发者DaveCheney提出了以下的编程原则:

简单性

  • 消除“多余的复杂性”,以简单清晰的逻辑编写代码
  • 不理解的代码无法修复改进

可读性

  • 代码是写给人看的,而不是机器
  • 编写可维护代码的第一步是确保代码可读

生产力

  • 团队整体工作效率非常重要

编写高质量的Go代码应从以下几个方面考虑:

1、代码格式:推荐使用gofmt自动格式化代码,gofmt是Go语言官方提供的工具,能自动格式化Go语言代码为官方统一风格,常见IDE都支持方便的配置

2、注释

①注释应该解释代码作用,例:

// Open opens the named file for reading. If successful,methods on
// the returned file can be used for reading; the associated file
// descriptor has mode 0_RDONLY.
// If there is an error, it will be of type *PathError.
func Open(name string)(*File,error){
		return OpenFile(name,0_RDONLY, 0) 
}

②注释应该解释代码如何做的,例:

// Add the Referer header from the most recent
// request URL to the new one, if it's not https->http: 
if ref := refererForURL(reqs[len(reqs)-1].URL,req.URL);ref !="" {
	 req.Header.Set("Referer", ref)
}

③注释应该解释代码实现的原因,例:

switch resp.StatusCode {
//..
case 307,308:
		redirectMethod = reqMethod 
		shouldRedirect = true 
		includeBody = true 
if treq.GetBody
	nil && ireq.outgoingLength() != 0 {
		// We had a request body, and 307/308 require
		// re-sending it,but GetBody is not defined.So just 
		// return this response to the user instead of an 
		// error, like we did in Go 1.7 and earlier. 
		shouldRedirect = false
		} 
}

④注释应该解释代码什么情况会出错,例:

// parseTimeZone parses a time zone string and returns its length. Time zones
// are human-generated and unpredictable. We can't do precise error checking.
// On the other hand, for a correct parse there must be a time zone at the 
//beginning of the string, so it's almost always true that there's one
// there. We look at the beginning of the string for a run of upper-case letters. 
// If there are more than 5, it's an error.
// If there are 4 or 5 and the last is a T, it's a time zone. // If there are 3, it's a time zone.
// Otherwise, other than special cases, it's not a time zone. 
// GMT is special because it can have an hour offset.
func parseTimeZone(value string) (length int, ok bool)

3、命名规范

①简洁胜于元长

② 缩略词全大写,但当其位于变量开头且不需要导出时,使用全小写

  • 例如使用ServeHTTP而不是ServeHttp
  • 使用XMLHTTPReguest或者xmlHTTPRequest

③变量距离其被使用的地方越远,则需要携带越多的上下文信息

  • 全局变量在其名字中需要更多的上下文信息,使得在不同地方可以轻易辩认出其含义

4、控制流程

  • 线性原理,处理逻辑尽量走直线,避免复杂的嵌套分支
  • 正常流程代码沿着屏幕向下移动
  • 提升代码可维护性和可读性
  • 故问题大多出现在复杂的条件语句和循环语句中

5、错误和异常处理

  • error尽可能提供简明的上下文信息链,方便定位问题
  • panic用于真正异常的情况
  • recover生效范围,在当前goroutine的被defer的函数中生效