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)强制类型转换时会导致显示上看似无问题,但是实际上字符串并不相同。
要解决这个问题需要对[]bytestring的转换过程进行一个封装。

这里实现了针对两种情况的解决方案,前者是遇到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. leetcode297. 二叉树的序列化与反序列化

    代码 /** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * ...

  2. 【SDOI 2014】数表

    题意 https://loj.ac/problem/2193 题解 ​显然就是求 $\sum\limits_{i=1}^{n} \sum\limits_{j=1}^{m} \sigma_1(\gcd{ ...

  3. supdf

    https://github.com/sumatrapdfreader/sumatrapdf/tree/master/src c++  java

  4. js获取前几个月的具体日期

    // 往前数monthNum月份,不能往后数monthNum getPreMonthDay("2018-12-28",20) // 往前数monthNum月份,不能往后数month ...

  5. python 单元测试_读写Excel及配置文件(八)

    一.安装openpyxl模块 openpyxl模块:是用于解决Excel(WPS等均可使用)中扩展名为xlsx/xlsm/xltx/xltm的文件读写的第三方库.xls文件要使用xlwt .wlrd两 ...

  6. HDU - 6583 Typewriter (后缀自动机+dp)

    题目链接 题意:你要打印一段字符串,往尾部添加一个字符需要花费p元,复制一段字符到尾部需要花费q元,求打印完全部字符的最小花费. 一开始想的贪心,后来发现忘了考虑p<q的情况了,还纳闷怎么不对. ...

  7. 爬虫相关基础技术铺垫---多线程Thread和队列Queue应用

    from queue import Queue from threading import Thread class mydownloader(Thread): def __init__(self,q ...

  8. 用DevExpress.textEdit控件限定数据录入格式

    例:只允许输入4位数字 第一步 第二部 例:只允许IP格式 设置Mask属性项的EditMask属性值为:(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5 ...

  9. Python语法汇总

    如果你之前学过任何一门编程语言,因为每种语言的基础语法要做的事情其实基本是相同的,只是表示方式或某些地方稍稍不同,因此在学Python的时候将它与其它你已经掌握的编程语言对比着学,这样学起来更快,效果 ...

  10. (转载)Ant自动编译打包android项目

    1  Ant自动编译打包android项目 1.1   Ant安装 ant的安装比较简单,下载ant压缩包  http://ant.apache.org  (最新的为1.9.3版本),下载之后将其解压 ...