• []byte和string和[]rune


    []byte 和 string 的区别

    这两个都经常用于初始化字符串,而且经常互相转换,很疑惑 []byte 究竟是什么

    声明的方式有2种:[]byte("hello world") 或者 []byte{97,98} 注意这里是ASCII码其实等价于 []byte("ab")

    打印看看:

    package main
    
    import "fmt"
    func main(){
        a := []byte{97,98}
        fmt.Println(a) // 输出[97 98]
        b := []byte("ab")
        fmt.Println((b)) // 输出[97 98]
    }

    但是写法不太一样

    b := []byte("Hello Gopher!") // 不要和 []byte{},[]byte{}是数组形式初始化[]byte,传递97那就是ASCII码97也就是对应的英文字母a
    b [1] = 'T' //允许修改

    s := "Hello Gopher!"
    s[1] = 'T' //被禁止 - 也就是字符串只能被替换不能被修改

    他们之间的转换(标准转换)是:

    // string to []byte
    s1 := "hello"
    b := []byte(s1)

    // []byte to string
    s2 := string(b)

    关于强转换这里暂不讨论;

    而golang之中,byte是uint8的别名,在go标准库builtin中有如下说明:

    // byte is an alias for uint8 and is equivalent to uint8 in all ways. It is
    // used, by convention, to distinguish byte values from 8-bit unsigned
    // integer values.
    type byte = uint8


    说人话,其实 []byte 本质上等于 []int8 (0-255整数=1个字节=8个2进制数)
    所以你会发现
    b := []byte("abcd")
    fmt.Println(b) // 打印结果是:[97 98 99 100]  这个97是ASCII码
    b = []byte("你好")
    fmt.Println(b) // 打印结果是:[228 189 160 229 165 189]


    而string的数据结构

    // string is the set of all strings of 8-bit bytes, conventionally but not
    // necessarily representing UTF-8-encoded text. A string may be empty, but
    // not nil. Values of string type are immutable.
    type string string

    说人话:string就是一个8位字节的集合(至于你要问我ascii、unicode之类的请看 https://blog.csdn.net/whocarea/article/details/87783614 )

     string经常被转换为 []byte 其实就是 字符串转换为一个 以ASCII码为值组成的数组 格式存储的数据

    [ ]rune 和 [ ]byte 有什么区别呢

    // byte is an alias for uint8 and is equivalent to uint8 in all ways. It is
    // used, by convention, to distinguish byte values from 8-bit unsigned
    // integer values.
    type byte = uint8
    
    // rune is an alias for int32 and is equivalent to int32 in all ways. It is
    // used, by convention, to distinguish character values from integer values.
    type rune = int32

    这样就很清晰了,一个是 1 个字节(8bit - 8个0/1符号),而8个2进制码最大数字(十进制)也就是255罢了,那么在Unicode编码之中,也就是英文码位;

    我们都知道,对于中文码位往往不止1个字节,也就是说他的数字应该更大一些:

    first := "社区"
    fmt.Println([]rune(first))  // [31038 21306] // 输出结果 [] rune
    fmt.Println([]byte(first)) // [231 164 190 229 140 186]// 输出结果 [] byte

    那么由上我们可以看出,关于字符串截取,为啥截取英文的用 string 转 [ ]byte就够了,而截取带有中文的使用 [ ]rune 会更合适

    因为字符串截取是将字符转为数组(unicode码位的,而byte并不能做到一个数组下标一个字符(因为字符是中文的话会被拆分为2个或更多个unit8)而rune可以不用考虑,rune的数字足够大,所有的中文码位都能被找打)所以rune可以绝对实现一个字符一个下标

    str := "a中文cd"
    str = string([]rune(str)[:4])
    fmt.Println(str)

    参考文章:

    https://segmentfault.com/a/1190000037679588 

    https://learnku.com/articles/23411/the-difference-between-rune-and-byte-of-go

    https://juejin.cn/post/6844903796930265096

    I can see a bigger world.
  • 相关阅读:
    Delphi提取EXE,DLL文件图标
    delphi 获取文件图标
    delphi 获取所有窗口标题
    SetWindowLong
    ASP.NET Core MVC添加区域Area,无法找到视图
    Unable to resolve service for type 'Microsoft.AspNetCore.Http.IHttpContextAccessor' while attempting
    pId的数据结构转children 数据结构(JS)
    VS发布网站时,报错提示:“未能将文件xxx复制到xxx,未能找到文件xx”三种解决方案!
    Multiple constructors accepting all given System.Collections.Generic.List
    javascript实现“系统可能不会保存您所做的更改 实现 是否离开”
  • 原文地址:https://www.cnblogs.com/xuweiqiang/p/14662875.html
Copyright © 2020-2023  润新知