zoukankan      html  css  js  c++  java
  • 转载 Golang []byte与string转换的一个误区

    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'是显示的值,其在内存中实际是48,也即0x30

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

    #include <stdio.h>
    #include <string.h>
    
    int main() {
        char s[] = {'a', 'b', 'c', '', '', 'd'};
        printf("%d %d %s
    ", 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
    ", 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])
    }
  • 相关阅读:
    致5年后的自己
    基础知识回顾——属性
    基础知识回顾——类和对象
    基础知识回顾——面向对象编程
    基础知识回顾——函数
    基础知识回顾——流程控制
    基础知识回顾——列表和字典
    基础知识回顾——元组和字符串
    基础知识回顾——通用序列操作
    XPath Checker和Firebug安装与使用
  • 原文地址:https://www.cnblogs.com/saolv/p/11768903.html
Copyright © 2011-2022 走看看