Golang中字符串的一个坑

华子 · · 11872 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

在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中字符串的一个坑

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

11872 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传