在C语言中,字符串的内存模型定义为以NUL
(\x0)结尾的字节数组。这是为大家所熟知的。
但是在Golang中并不是如此,Golang中的字符串abc
和abc\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
}
有疑问加站长微信联系(非本文作者)