前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >你可能不知道的Go语言小细节

你可能不知道的Go语言小细节

作者头像
博文视点Broadview
发布2023-12-20 12:56:37
1030
发布2023-12-20 12:56:37
举报

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

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

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

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

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

01

数字字面量

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

代码语言:javascript
复制
v1 := 0b00101101 // 二进制字面量
v2 := 0o377      // 八进制字面量
v3 := 0x1p-2     // 十六进制浮点字面量
v4 := 01e2       // 十进制浮点字面量

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

代码语言:javascript
复制
v5 := 123_456  // 可以使用_分隔数字

02

切片表达式

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

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

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

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

代码语言:javascript
复制
// 对数组取切片
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))

输出:

代码语言:javascript
复制
s:[2 3] type:[]int len:2 cap:4
s2:el type:string len:2

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

代码语言:javascript
复制
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。

代码语言:javascript
复制
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))

输出:

代码语言:javascript
复制
s:[2 3] len:2 cap:4
s2:[5] len:1 cap:1

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

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

代码语言:javascript
复制
a[low:high:max]

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

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

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

代码语言:javascript
复制
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))

输出结果:

代码语言:javascript
复制
s1:[2 3] len:2 cap:2
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标识。

代码语言:javascript
复制
❯ 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 参数。

代码语言:javascript
复制
❯ 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,我们并不希望转义&符号。

代码语言:javascript
复制
// 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"})
}

输出结果如下:

代码语言:javascript
复制
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语言之路》这本书是七米对Go语言学习方法的一次系统性总结。

作为国内较早一批Go语言爱好者,作者把他自己学习Go语言的经验总结下来,将Go语言的相关知识点全部串联起来,完整地介绍了如何从零开始学习Go语言。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-12-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 博文视点Broadview 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 切片表达式
相关产品与服务
腾讯云服务器利旧
云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档