Go——习惯用法

Go语言对代码质量有严格要求,如不允许未使用的变量和包,强制使用gofmt统一代码风格。comma,ok表达式用于安全地获取map和通道值。类型断言通过接口和实例类型的检查。此外,Go支持简写模式,如多包导入和变量声明。包内常有导出和非导出的同名函数,用于功能封装和逻辑隔离。多值返回函数中,error通常作为最后一个返回值。
摘要由CSDN通过智能技术生成

1、干净与强迫症

Go在代码干净上有了近乎苛刻的要求,主要体现在如下几个方面:

  1. 编译器不能通过未使用的局部变量(包括未使用的标签)。
  2. “import”未使用的包同样通不过编译。
  3. 所有的控制结构、函数和方法定义的“(”放到行尾,而不能另起一行。
  4. 提供go fmt工具格式化代码,使所有的代码风格保持统一。

Go对代码的干净和整洁要求到了强迫症的程度,但这是一种好的约束,虽然很多人难以接
受。

2、comma,ok表达式

  1. 获取map值。
    获取map中不存在键的值不会发生异常,而是会返回值类型的零值,如果想确定map中是否存在key,则可以使用获取map值的comma,ok语法。示例如下:
m := make(map[string]string)

v,ok :=  m["some"]
//通过ok进行判断
if !ok {
	println ("m[some]is nil")
else
	println ("m[some]="v)
}
  1. 读取chan的值
    读取已经关闭的通道,不会阻塞,也不会引起panic,而是一直返回该通道的零值。怎么判断通道已经关闭?有两种方法,一种是读取通道的comma,ok表达式,如果通道已经关闭,则ok的返回值是fasle,另一种就是通过range循环迭代。示例如下:
c := make(chan int)
go func(){
	c<-1
	c<-2
	close(c)
}()

for {
	//使用comma,ok判断通道是否关闭
	v,ok :<-c
	if ok {
		printIn (v)
	} else
		break
	}
}

//使用range更加简洁
for v := range c {
	println (v)
}
  1. 类型断言(type assertion)
    接口断言通常可以使用comma,ok语句来确定接口是否绑定某个实例类型,或者判断接口绑定的实例类型是否实现另一个接口。示例如下:
//如下代码片段摘自标准包src/net/http/request.go
//判断接口body绑定的实例是否实现了另一个接口类型io.ReadCloser
783 rc,ok := body.(io.Readcloser)

//判断接口Body绑定的实例类型是否是*maxBytesReader具体类型
1107 if,ok :r.Body.(*maxBytesReader);!ok {

3、简写模式

G0语言很多重复的引用或声明可以用“()”进行简写。

  1. import多个包。例如:
//推荐写法
import (
	"bufio"
	"bytes"
)

//不推荐写法
import "bufio"
import "bytes"
  1. 多个变量声明。
    包中多个相关全局变量声明时,建议使用“()”进行合并声明。示例如下:
//推荐这样的写法
var (
	bufioReaderPool
	sync.Pool
	bufioWriter2kPool sync.Pool
	bufioWriter4kPool sync.Pool
)

//不推荐这样的写法
var bufioReaderPool sync.Pool
var bufioWriter2kPool sync.Pool
var bufioWriter4kPool sync.Pool

4、包中的函数或方法设计

很多包的开发者会在内部实现两个“同名”的函数或方法,一个首字母大写,用于导出API供外部调用;一个首字母小写,用于实现具体逻辑。一般首字母大写的函数调用首字母小写的函数,同时包装一些功能;首字母小写的函数负责更多的底层细节。

大部分情况下我们不需要两个同名且只是首字母大小写不同的函数,只有在函数逻辑很复杂,而且函数在包的内、外部都被调用的情况下,才考虑拆分为两个函数进行实现。一方面减少单个函数的复杂性,另一方面进行调用隔离。这种编程技术在标准库database/sql里面体现得最明显。

5、多值返回函数

多值返回函数里如果有eror或bool类型的返回值,则应该将eror或bool作为最后一个返回值。这是一种编程风格,没有对错。Go标准库的写法也遵循这样的规则。当绝大多数人都遵照这种写法时,如果不遵循这种“潜规则”,则写出的代码让别人读起来很别扭。示例如下:

//分析标准库bytes的代码可以看到这种习惯用法
//cd $GOROOT/src/bytes/&&egrep 'func.*error\)Ifunc.*bool\)'-r -nIgrep -v 'test!
buffer.go:107:func (b *Buffer)tryGrowByReslice(n int)(int,bool){
buffer.go:335:func (b *Buffer)ReadByte()(byte,error){
reader.go:66:func (r *Reader)ReadByte()(byte,error){
reader.go:113:func (r *Reader)Seek(offset int64,whence int)(int64,error)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值