Golang []byte与string转换的一个误区

https://www.oyohyee.com/post/Note/golang_byte_to_string/

2019-08-10 23:46:31

610

在实现[]byte转换string的过程中,发现了一个很容易理解错误的地方。

注意:这里要区分0,'\0','0'的区别。其中前两者等价,是内存中实际的值。而'0'是显示的值,其在内存中实际是48,也即0x30

在C语言中,字符串的结尾是'\0',也即字节为0的字符。

#include <stdio.h>
#include <string.h> int main() {
char s[] = {'a', 'b', 'c', '\0', '\0', 'd'};
printf("%d %d %s\n", strlen(s), sizeof(s), s); return 0;
}

这个程序输出的内容是3 6 abc


而在Go语言中,字符串仅仅把对应字节为0的字符认为是空字符,不显示但是仍然占用长度。

package main

import (
"fmt"
) func main() {
b := []byte{'a', 'b', 'c', 0, 0, 'd'}
s := string(b)
fmt.Printf("%d %s %s\n", len(s), s, b)
}

这个程序输出的内容是6 abcd abcd

0在C语言以及Go语言不同的表现在大部分情况下不会造成问题,但是当使用io.Reader(b []byte)时,如果传入的字节数组b本身长度大于reader可读到的长度,则会导致末尾被0补齐。当直接使用string(b)强制类型转换时会导致显示上看似无问题,但是实际上字符串并不相同。
要解决这个问题需要对[]byte和string的转换过程进行一个封装。

这里实现了针对两种情况的解决方案,前者是遇到0就结束转换,后者则是忽略所有的0并将剩余部分拼接

// String 将 `[]byte` 转换为 `string`
func String(b []byte) string {
for idx, c := range b {
if c == 0 {
return string(b[:idx])
}
}
return string(b)
} // StringWithoutZero 将 `[]byte` 转换为 `string`
func StringWithoutZero(b []byte) string {
s := make([]rune, len(b))
offset := 0
for i, c := range b {
if c == 0 {
offset++
} else {
s[i-offset] = rune(c)
}
}
return string(s[:len(b)-offset-1])
}

转载 Golang []byte与string转换的一个误区的更多相关文章

  1. golang []byte和string的高性能转换

    golang []byte和string的高性能转换 在fasthttp的最佳实践中有这么一句话: Avoid conversion between []byte and string, since ...

  2. golang []byte 和 string相互转换

    原文链接:golang []byte和string相互转换 测试例子 package main import ( "fmt" ) func main() { str2 := &qu ...

  3. golang byte转string 字节数组转字符串的问题

    golang语言本身就是c的工具集,开发c的程序用到的大部分结构体,内存管理,携程等,golang基本都有,他只是在这个基础上又加了一些概念这里说一个很小的问题,就是字节数组转string的问题,网上 ...

  4. golang []byte转string

    golang中,字符切片[]byte转换成string最简单的方式是 package main import ( "fmt" _ "unsafe" ) func ...

  5. golang []byte和string相互转换

    测试例子 package main   import (     "fmt" )   func main() {     str2 := "hello"     ...

  6. 关于byte[]与string、Image转换

    byte[]与string转换 参考网址:https://www.cnblogs.com/xskblog/p/6179689.html 1.使用System.Text.Encoding.Default ...

  7. Golang的Json encode/decode以及[]byte和string的转换

    使用了太长时间的python,对于强类型的Golang适应起来稍微有点费力,不过操作一次之后发现,只有这么严格的类型规定,才能让数据尽量减少在传输和解析过程中的错误.我尝试使用Golang创建了一个公 ...

  8. Java中String和byte[]间的 转换浅析

    Java语言中字符串类型和字节数组类型相互之间的转换经常发生,网上的分析及代码也比较多,本文将分析总结常规的byte[]和String间的转换以及十六进制String和byte[]间相互转换的原理及实 ...

  9. C# Byte[] 转String 无损转换

    C# Byte[] 转String 无损转换 转载请注明出处 http://www.cnblogs.com/Huerye/ /// <summary> /// string 转成byte[ ...

随机推荐

  1. 大型分布式爬虫准备 scrapy + request

    那些高手 爬虫好文 而我避免这些问题的方式,控制台清除所有定时 var id = setInterval(function() {}, 0); while (id--) clearInterval(i ...

  2. openCV3测试指南

    本文来源于https://docs.opencv.org/3.4.1/db/df5/tutorial_linux_gcc_cmake.html 经测试整理后发布 上一节安装完成了openCV,这一节进 ...

  3. svn使用教程(收藏)

    SVN简介: 为什么要使用SVN? 程序员在编写程序的过程中,每个程序员都会生成很多不同的版本,这就需要程序员有效的管理代码,在需要的时候可以迅速,准确取出相应的版本. Subversion是什么? ...

  4. React 服务器端渲染流程

    其实我们在访问客户端渲染的页面时,请求到的只是一个 html 空壳,里面引入了一个 js 文件,所有的内容都是通过 js 进行插入的,正是因为页面是由 js 渲染出来的,所以会带来如下几个问题: 1. ...

  5. autofs 自动挂载.

    autofs 自动挂载. 操作环境:redhat 6 一.autofs 说明 自动挂载器是一个监视目录的守护进程,并在目标子目录被引用时,自动执行预定义的挂载 自动挂载器由autofs服务脚本管理 自 ...

  6. LOJ-6284-数列分块入门8

    链接: https://loj.ac/problem/6284 题意: 给出一个长为 的数列,以及 个操作,操作涉及区间询问等于一个数 的元素,并将这个区间的所有元素改为 . 思路: 维护一个分块是否 ...

  7. 赋值语句C++(面宝P29)

    ; void main(){ int i=i; } 解析:main里面的i从声明的那一刻就是可见的了,所以main里的i不是1,而是一个未定义的值. 这段代码ctrl+F7编译能通过(有警告如下) c ...

  8. 【NOIP2017提高A组模拟9.5】心灵治愈

    题目 好吧,我表示比赛时完全看不懂题目 题目解释 良心的出题人为一道两三句可以讲清楚的题目,又写了一大坨恶心的解释. 容斥 其实题目就是有个数组a[1~n+1],已知a[n+1]=m,1<=a[ ...

  9. Redis——SpringBoot项目使用Lettuce和Jedis接入Redis集群

    Jedis连接Redis: 非线程安全 如果是多线程环境下共用一个Jedis连接池,会产生线程安全问题,可以通过创建多个Jedis实例来解决,但是创建许多socket会影响性能,因此好一点的方法是使用 ...

  10. C# winform 发布的时候没有app.config去哪儿了?

    有时候winform发布的时候app.config不见了? 1.我们来到生成文件的目录下 找到后缀是 .config 的文件右击,打开,也可以用其他方式打卡,我这里使用的是sublime这个文本编辑器 ...