Go语言开发技巧必知的小细节提升效率

 更新时间:2024年01月11日 11:17:39   作者:Go语言中文网  
这篇文章主要介绍了Go语言开发技巧必知的小细节提升效率,分享几个你可能不知道的Go语言小细节,希望能帮助大家更好地学习这门语言

引言

近年来,Go语言迅速占领了开发领域的重要地位,成为众多公司和开发者的首选语言。

其简捷、高效、并发性强的特点使得它在处理大型系统和复杂工程问题时表现出色,为开发者提供了良好的体验。

随着云计算、容器化、微服务、服务网格等技术的兴起,Go语言的应用场景愈发广泛,这也进一步推动其社区的繁荣和发展。

可以预见,Go语言的发展前景将会更加广阔。

本文分享几个你可能不知道的Go语言小细节,希望能帮助大家更好地学习这门语言~~

01 数字字面量

Go语言中声明数字变量时,可以使用数字字面量让开发者以二进制、八进制或十六进制浮点数的格式定义数字。例如:

v1 := 0b00101101 // 二进制字面量 

v2 := 0o377      // 八进制字面量 

v3 := 0x1p-2     // 十六进制浮点字面量 

v4 := 01e2       // 十进制浮点字面量

在表达数字字面量时,可以使用_分隔数字。例如:

v5 := 123_456  // 可以使用_分隔数字

02 切片表达式

切片表达式指从字符串、数组、指向数组或切片的指针构造子字符串或切片。

它有两种变体,其中一种是指定low和high两个索引界限值。

由于切片的底层是数组,所以我们可以基于数组通过切片表达式得到切片,切片表达式中的low和high表示索引范围(左包含,右不包含)。

例如,下面的代码表示从数组a中选出1≤索引值<4的元素组成切片s,切片s的长度为high-low,容量为其底层数组的容量。

// 对数组取切片
a := [5]int{1, 2, 3, 4, 5}
s := a[1:3] // s := a[low:high]
fmt.Printf("s:%v type:%T len:%v cap:%v\n", s, s, len(s), cap(s))
// 对字符串取切片得到的还是字符串类型
b := "hello world"
s2 := b[1:3] // s2 := b[low:high]
fmt.Printf("s2:%v type:%T len:%v\n", s2, s2, len(s2))

输出:

s:[2 3] type:[]int len:2 cap:4

s2:el type:string len:2

方便起见,可以省略切片表达式中的任何索引。如果省略low则默认为0,如果省略high则默认为切片操作数的长度。

a[2:]  // 等同于 a[2:len(a)]

a[:3]  // 等同于 a[0:3]

a[:]   // 等同于 a[0:len(a)]

注意:对于数组或字符串,如果0 ≤ low ≤ high ≤ len(a),则索引合法;否则会索引越界(out of range)。

对切片再执行切片表达式时(切片再切片),high的上限是切片的容量cap(a),而不是长度。

常量索引必须是非负的,并且可以用int类型的值表示。

对于数组或常量字符串,常量索引必须在有效范围内。

如果low和high两个指标都是常数,则它们必须满足low≤high。

如果索引在运行时超出范围,就会发生运行时panic。

a := [5]int{1, 2, 3, 4, 5}
s := a[1:3] // s := a[low:high]
fmt.Printf("s:%v len:%v cap:%v\n", s, len(s), cap(s))
s2 := s[3:4] // 索引的上限是cap(s)而不是len(s)
fmt.Printf("s2:%v len:%v cap:%v\n", s2, len(s2), cap(s2))

输出:

s:[2 3] len:2 cap:4

s2:[5] len:1 cap:1

另一种变体是除了指定low和high索引界限值,还指定容量的完整形式。

注意:字符串不支持完整切片表达式。

a[low:high:max]

上面的代码会构造与简单切片表达式a[low:high]的类型、长度和元素相同的切片。

另外,它会将得到的结果切片的容量设置为max-low。

在完整切片表达式中只有第一个索引值(low)可以省略,该值默认为0。

a := [5]int{1, 2, 3, 4, 5}
s1 := a[1:3:4] // 通过额外指定max,控制切片的容量
fmt.Printf("s1:%v len:%v cap:%v\n", s1, len(s1), cap(s1))
s2 := a[1:3]
fmt.Printf("s2:%v len:%v cap:%v\n", s2, len(s2), cap(s2))

输出结果:

s1:[2 3] len:2 cap:3

s2:[2 3] len:2 cap:4

完整切片表达式需要满足的条件是0 ≤ low ≤ high ≤ max ≤ cap(a),其他条件和简单切片表达式相同。

03 go test cache

在包列表模式下,go test会缓存测试成功的包的测试结果,以避免运行不必要的重复测试。

当测试结果可以从缓存中获取时,go test将直接显示以前缓存的输出,而不是再次运行测试二进制文件。

当这种情况发生时,go test会输出(cached)来代替摘要行中的运行时间。 

执行两次 go test . -v,从下面的输出结果可以看到,第二次的输出结果中有cached标识。

❯ go test . -v
=== RUN   TestSplit
--- PASS: TestSplit (0.00s)
PASS
ok   split 0.005s
❯ go test . -v
=== RUN   TestSplit
--- PASS: TestSplit (0.00s)
PASS
ok   split (cached)

如果多次执行测试时运行的二进制文件相同,并且命令行上的参数都是可缓存测试参数(-bachtime、-cpu、-list、-pallel、-run、-short、-timeout、-failfast和-v),就会匹配到缓存中的结果。

只要测试时添加了除上述可缓存参数外的任何参数就不会缓存结果,显式禁用测试缓存的惯用方法是在命令行使用 -count=1 参数。

❯ go test . -v -count=1
=== RUN   TestSplit
--- PASS: TestSplit (0.00s)
PASS
ok   split 0.005s

04 JSON序列化时不转义

json包中的encoder可以通过SetEscapeHTML指定是否应该在JSON字符串中转义有问题的HTML字符。

它默认将&、<和>转义为\u0026、\u003c和\u003e,以避免在HTML中嵌入JSON时出现安全问题。

如果在是非HTML场景下不想被转义,那么可以通过SetEscapeHTML(false)禁用此行为。

例如,在有些业务场景下可能需要序列化带查询参数的URL,我们并不希望转义&符号。

// URLInfo 一个包含URL字段的结构体
type URLInfo struct {
URL string
// ...
}
func jsonEncodeDontEscapeHTML(data URLInfo) {
// 默认序列化时会转义 &、<和>
b, _ := json.Marshal(data)
fmt.Printf("json.Marshal(data) result:%s\n", b)
// 通过 SetEscapeHTML(false) 设置不转义
buf := bytes.Buffer{}
encoder := json.NewEncoder(&buf)
encoder.SetEscapeHTML(false)
encoder.Encode(data)
fmt.Printf("encoder.Encode(data) result:%s\n", buf.String())
}
func main() {
jsonEncodeDontEscapeHTML(URLInfo{URL:"https://liwenzhou.com?name=q1mi&age=18"})
}

输出结果如下:

json.Marshal(data) 

result:{"URL":"https://liwenzhou.com?name=q1mi\u0026age=18"}

encoder.Encode(data) 

result:{"URL":"https://liwenzhou.com?name=q1mi&age=18"}

以上就是Go语言开发技巧必知的小细节提升效率的详细内容,更多关于Go语言开发技巧的资料请关注脚本之家其它相关文章!

相关文章

  • Go语言压缩和解压缩tar.gz文件的方法

    Go语言压缩和解压缩tar.gz文件的方法

    这篇文章主要介绍了Go语言压缩和解压缩tar.gz文件的方法,实例分析了使用Go语言压缩文件与解压文件的技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-02-02
  • 一起来用GoLand开发第一个Go程序

    一起来用GoLand开发第一个Go程序

    当您在编辑器中工作时GoLand 会分析您的代码,寻找优化方法,并检测潜在和实际问题,下面这篇文章主要给大家介绍了关于用GoLand开发第一个Go程序的相关资料,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2022-12-12
  • 使用Go语言实现找出两个大文件中相同的记录

    使用Go语言实现找出两个大文件中相同的记录

    这篇文章主要为大家详细介绍了使用Go语言实现找出两个大文件中相同的记录的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-10-10
  • golang中随机数rand的使用

    golang中随机数rand的使用

    本文主要介绍了golang中随机数rand的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • Golang使用ini库读取配置详情

    Golang使用ini库读取配置详情

    这篇文章主要介绍了Golang使用ini库读取配置详情,go-ini是一个非常方便、高效的go配置文件操作库。使用它在项目中读取和修改配置文件,下文相关资料需要的小伙伴可可以参考一下
    2022-04-04
  • GO的range具体使用

    GO的range具体使用

    GO语言的for…range 能做什么呢?golang的for…range是go 身的语法,可以用来遍历数据结构,本文就详细的来介绍一下具体使用,感兴趣的可以了解一下
    2021-10-10
  • 拦截信号Golang应用优雅关闭的操作方法

    拦截信号Golang应用优雅关闭的操作方法

    这篇文章主要介绍了拦截信号优雅关闭Golang应用,本文介绍了信号的概念及常用信号,并给出了应用广泛的几个示例,例如优雅地关闭应用服务、在命令行应用中接收终止命令,需要的朋友可以参考下
    2023-02-02
  • Go语言Web编程实现Get和Post请求发送与解析的方法详解

    Go语言Web编程实现Get和Post请求发送与解析的方法详解

    这篇文章主要介绍了Go语言Web编程实现Get和Post请求发送与解析的方法,结合实例形式分析了Go语言客户端、服务器端结合实现web数据get、post发送与接收数据的相关操作技巧,需要的朋友可以参考下
    2017-06-06
  • 构建Golang应用最小Docker镜像的实现

    构建Golang应用最小Docker镜像的实现

    这篇文章主要介绍了构建Golang应用最小Docker镜像的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-05-05
  • Golang函数这些神操作你知道哪些

    Golang函数这些神操作你知道哪些

    这篇文章主要为大家介绍了一些Golang中函数的神操作,不知道你都知道哪些呢?文中的示例代码讲解详细,具有一定的学习价值,需要的可以参考一下
    2023-02-02

最新评论