【问题标题】:When to use []byte or string in Go?何时在 Go 中使用 []byte 或 string?
【发布时间】:2012-06-05 07:12:08
【问题描述】:

在编写 Go 应用程序时,我发现自己可以选择使用 []bytestring。除了[]byte 的明显可变性之外,我如何决定使用哪一个?

我有几个用例示例:

  1. 函数返回一个新的[]byte。既然切片容量是固定的,那有什么理由不返回字符串呢?
  2. 默认情况下,[]byte 的打印效果不如string,因此我经常发现自己转换为string 以进行日志记录。应该一直是string吗?
  3. 添加[]byte 时,始终会创建一个新的底层数组。如果要添加的数据是常量,为什么不应该是 string

【问题讨论】:

  • 这听起来取决于你的使用。如果你打算和他们一起做字符串操作,那就叫它string。如果只是不透明的数据被打乱,为什么不[]byte?它归结为用例。
  • 如果您需要处理单个字符,而不是 UTF-8 编码字节流,请先将其转换为符文(32 位整数 IIRC)。
  • 那么还有[]rune,最好表示可变字符串
  • 可变性确实是字符串与字节切片或符文之间的关键区别。如果修改了原始数组,则在处理切片时会出现许多细微差别——例如,该数组的切片被用作映射中的键或存储在其他地方的情况。尽量避免陷入将切片视为固定元组的习惯——它们实际上更像是有长度的 C 指针。
  • Go 有一个名为rune 的类型?我对 Google 的看法有所上升。

标签: string bytearray go


【解决方案1】:

我的建议是在处理文本时默认使用字符串。但如果满足以下条件之一,请改用 []byte:

  • []byte 的可变性将显着减少所需的分配数量。

  • 您正在处理使用 []byte 的 API,避免转换为字符串将简化您的代码。

【讨论】:

  • 不应该考虑我们是否只处理 ASCII 字符的情况吗?因为如果不是,byte 不能容纳这样的字符,我们需要使用 rune
  • A []byte 可以保存非 ASCII 字符,如果它们被编码为字节(例如,在 UTF-8 中)。
  • 我假设在这种情况下我们可能没有 1-1 字符字节映射(UTF-8 代码点可能表示为 1 到 4 bytes)。
  • 没错。但string 也是如此。
  • 我经常发现转换为字符串很方便,因为缺少对字节数组不起作用的扫描函数。但是转换为字符串是不必要的复制。处理大文件时,最好不要转换为可能的字符串。它提供了巨大的性能提升
【解决方案2】:

我的感觉是,在 Go 中,比在任何其他非 ML 风格的语言中,类型更用于传达意义和预期用途。因此,确定使用哪种类型的最佳方法是问问自己数据是什么

字符串代表文本。只是文字。编码不是您必须担心的事情,所有操作都在逐个字符的基础上进行,无论“字符”实际上是什么。

数组表示二进制数据或该数据的特定编码。 []byte 表示数据要么只是一个字节流,要么是一个单字节字符流。 []int16 代表一个整数流或两个字节字符的流。

考虑到几乎所有处理字节的东西也有处理字符串的函数,反之亦然,我建议不要问你需要对数据做什么,而是问数据代表什么。找出瓶颈后进行优化。

编辑:This post 是我使用类型转换分解字符串的基本原理。

【讨论】:

    【解决方案3】:
    1. 一个区别是返回的[]byte 可能是 重用于保存另一个/新数据(没有新的内存分配),而 string 不能。另一个是,在 gc 实现中 至少,string 是比[]byte 小一个字的实体。可 用于在有大量此类项目时节省一些内存。

    2. 无需将 []byte 转换为 string 以进行日志记录。典型的“文本”动词,如 %s%q 适用于 string[]byte 表达式 相等。在另一个方向上同样适用于例如%x% 02x

    3. 取决于执行连接的原因以及结果是否存在 之后再次与/某物/其他地方结合。如果是这种情况,那么[]byte 的表现可能会更好。

    【讨论】:

    • FWIW,%v 说明符将 []byte 视为整数数组,这是非 -f 方法的默认值。还有返回切片而不是将它们作为参数的函数呢?
    • “字符串是比 []byte 小一个单词的实体”是什么意思?
    • @animaacija 发表评论已经快一年了,但我想我会回答:因为strings 是不可变的,它们在内部表示为指针和长度,而[]bytes也需要容量。
    猜你喜欢
    • 2013-05-20
    • 2017-09-14
    • 1970-01-01
    • 2019-04-23
    • 2010-11-02
    • 2012-01-17
    • 2019-11-28
    • 1970-01-01
    • 2013-02-15
    相关资源
    最近更新 更多