前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go语言中常见100问题-#40 Useless string conversions

Go语言中常见100问题-#40 Useless string conversions

作者头像
数据小冰
发布2023-08-17 08:33:53
1030
发布2023-08-17 08:33:53
举报
文章被收录于专栏:数据小冰数据小冰
无意义的字符串转换

当编码操作的类型既可以是 []byte 又可以是 string时,大多数程序员倾向使用string类型,因为这样可能更方便。但是大多数的 I/O 操作采用的类型是 []byte。例如 io.Readerio.Writerio.ReadAll. 如果拿到的类型是string,但又要使用这些接口意味着需要进行类型转换,strings包提供了相关的转换函数。

下面看一个没有必要进行转换的例子。getBytes函数从入参io.Reader中读取字节流,然后调用sanitize函数,去掉首尾的空白符。

代码语言:javascript
复制
func getBytes(reader io.Reader) ([]byte, error) {
 b, err := io.ReadAll(reader)
 if err != nil {
  return nil, err
 }
 // call sanitize
}

io.ReadAll返回的是字节切片(赋值给b),sanitize函数如何实现呢?一种思路是接收一个string参数返回值也是string,内部调用strings包的TrimSpace处理。

代码语言:javascript
复制
func sanitize(s string) string {
 return strings.TrimSpace(s)
}

回到getBytes函数,拿到的b是[]byte,需要将其转换为string才能调用sanitize,对于返回值,由于sanitize返回的是字符串,但是getBytes返回的是[]byte,所以也需要进行逆向转换。

代码语言:javascript
复制
return []byte(sanitize(string(b))),nil

看到这里实现存在的问题了吗?我们需要进行额外的转换,将[]byte转为string,返回的时候又要将string转回为[]byte. 每次转换需要分配额外的内存,尽管string的内部也有一个[]byte,但是转换为[]byte需要将string内部[]byte中的内容拷贝新分配的[]byte中,因为字符串string不可变特性。

字符串不可变特性

可以通过一段代码验证字符串的不可变特性,如下所示。字节切片b由字符a、b、c构成,然后通过b创建字符串s, 现在修改切片b中第二位置元素,即从b换成x,然后打印字符串s,观察s是否为axc.

代码语言:javascript
复制
b := []byte{'a', 'b', 'c'}
s := string(b)
b[1] = 'x'
fmt.Println(s)

实际运行输出的是abc而不是axc,可以验证s和b不是共享同一个切片。

那如何实现 sanitize函数呢?将其入参和返回值类型都改为[]byte类型,这样就不用进行额外转换。

代码语言:javascript
复制
func sanitize(b []byte) []byte {
 return bytes.TrimSpace(b)
}

bytes包也有去除空白符函数TrimSpace,直接调用bytes.TrimSpace,不需要额外转换。

代码语言:javascript
复制
return sanitize(b), nil

总结,大多数I/O操作处理的是[]byte,而不是string. 当我们不是很明确到底是采用[]byte还是string时候,应想到本文举的例子,使用[]byte不一定没有string方便,像strings包提供的常用函数:Split、Count、Contains、Index 在bytes包中也有一样的函数。因此,在处理I/O操作时,我们应该首先想到使用[]byte而不是string,避免额外的转换开销。

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

本文分享自 数据小冰 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 无意义的字符串转换
    • 字符串不可变特性
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档