Golang中字符串的一个坑

在C语言中,字符串的内存模型定义为以NUL(\x0)结尾的字节数组。这是为大家所熟知的。

但是在Golang中并不是如此,Golang中的字符串abcabc\x0\x0并不相当,所以说Golang明确规定了字符串的长度,而不是以\x0为结尾来判断的。

下面看示例代码:

package main

import (
    "fmt"
    "os"
)

func main() {
    var a[5]byte = [5]byte{'a','b','c'}
    var b[]byte = []byte{'a','b','c'}

    fmt.Printf("len(a): %d, %q\n", len(a), a)
    fmt.Printf("len(b): %d, %q\n", len(b), b)

    slice_a := a[:]
    str_a := string(slice_a)
    str_b := string(b)
    fmt.Printf("len(str_a): %d, %q:%s\n", len(str_a), str_a, str_a)
    fmt.Printf("len(str_b): %d, %q:%s\n", len(str_b), str_b, str_b)

    if str_a == str_b {
        fmt.Println("str_a == str_b")
    } else {
        fmt.Println("str_a != str_b")
    }

    file, err := os.Create(str_a)
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println(file)
}

代码输出为:

len(a): 5, "abc\x00\x00"
len(b): 3, "abc"
len(str_a): 5, "abc\x00\x00":abc
len(str_b): 3, "abc":abc
str_a != str_b

open abc: invalid argument


数组a长度为5,最后两个字节为\x00。切片b长度为3,有效内容为abc。 分别将a和b转换为string类型后,数组a中包含的\x00也被保留下来,所以在对比时,这两者的长度不可能相等的。

当然这还不是最关键的,问题处在当用str_a作为文件名创建文件时file, err := os.Create(str_a),系统会报错:open abc: invalid argument。说明这不是一个有效的路径名称。

Golang是一种强类的语言,对于数组来说[3]byte[5]byte并不是同一个类型,不能通用。 当然,数组和切片也更不可能是同一个类型。

解决办法是,迭代数组中的字节,跳过为0的字节:

func GetValidByte(src []byte) []byte {
    var str_buf []byte
    for _, v := range src {
        if v != 0 {
            str_buf = append(str_buf, v)
        }
    }
    return str_buf
}

本文来自:天地孤影任我行

感谢作者:华子

查看原文:Golang中字符串的一个坑

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。