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语言中的方法集合与选择receiver类型

    浅析Go语言中的方法集合与选择receiver类型

    这篇文章主要为大家详细介绍了Go语言中的方法集合与选择receiver类型的相关知识,文中的示例代码讲解详细,对我们深入学习go语言有一定的帮助,需要的可以参考下
    2023-11-11
  • Golang实现自定义recovery中间件

    Golang实现自定义recovery中间件

    在 Golang 的 Web 项目中,自定义 recovery 中间件是一种常见的做法,用于捕获并处理应用程序的运行时错误,下面我们就来看看具体如何实现吧
    2023-09-09
  • Hugo Config模块构建实现源码剖析

    Hugo Config模块构建实现源码剖析

    这篇文章主要为大家介绍了Hugo Config模块构建实现源码剖析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-02-02
  • GO制作微信机器人的流程分析

    GO制作微信机器人的流程分析

    这篇文章主要介绍了利用go制作微信机器人,本文主要包括项目基础配置及详细代码讲解,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-08-08
  • Goland激活码破解永久版及安装详细教程(亲测可以)

    Goland激活码破解永久版及安装详细教程(亲测可以)

    这篇文章主要介绍了Goland激活码破解永久版及安装详细教程(亲测可以),本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-10-10
  • golang实现页面静态化操作的示例代码

    golang实现页面静态化操作的示例代码

    这篇文章主要介绍了golang实现页面静态化操作的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02
  • golang正则之命名分组方式

    golang正则之命名分组方式

    这篇文章主要介绍了golang正则之命名分组方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04
  • Golang中如何使用lua进行扩展详解

    Golang中如何使用lua进行扩展详解

    这篇文章主要给大家介绍了关于Golang中如何使用lua进行扩展的相关资料,这是最近在工作中遇到的一个问题,觉着有必要分享出来给大家学习,文中给出了详细的示例,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-10-10
  • golang对etcd存取和数值监测的实现

    golang对etcd存取和数值监测的实现

    这篇文章主要介绍了golang对etcd存取和数值监测的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-09-09
  • Go语言题解LeetCode888公平糖果交换示例详解

    Go语言题解LeetCode888公平糖果交换示例详解

    这篇文章主要为大家介绍了Go语言题解LeetCode888公平糖果交换示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12

最新评论