如何在go中有效地连接字符串

问题描述

新方法:

从 Go 1.10 开始,有一种strings.Builder类型

旧方式:

使用bytes包。它有一个Buffer实现io.Writer.

package main

import (
    "bytes"
    "fmt"
)

func main() {
    var buffer bytes.Buffer

    for i := 0; i < 1000; i++ {
        buffer.WriteString("a")
    }

    fmt.Println(buffer.String())
}

这是在 O(n) 时间内完成的。

在 Go 1.10+ 中,这里有

Builder 用于使用 Write 方法有效地构建字符串。它最大限度地减少了内存复制。零值即可使用。

例子

bytes.Buffer.

package main

import (
    "strings"
    "fmt"
)

func main() {
    // ZERO-VALUE:
    //
    // It's ready to use from the get-go.
    // You don't need to initialize it.
    var sb strings.Builder

    for i := 0; i < 1000; i++ {
        sb.WriteString("a")
    }

    fmt.Println(sb.String())
}

单击以在操场上查看此内容

支持的接口

StringBuilder 的方法是在考虑现有接口的情况下实现的。这样您就可以在代码中轻松切换到新的 Builder 类型。

与 bytes.Buffer 的区别

  • 它只能增长或重置。

  • 它有一个内置的 copyCheck 机制,可以防止意外复制它:

func (b *Builder) copyCheck() { ... }

  • bytes.Buffer,一个可以访问这样的底层字节:(*Buffer).Bytes()

  • strings.Builder 防止这个问题。

  • 有时,这不是问题,而是需要。
  • 例如:对于将字节传递给io.Reader等时的偷看行为。

  • bytes.Buffer.Reset() 倒带并重用底层缓冲区,而strings.Builder.Reset() 不会,它分离缓冲区。

笔记

  • 不要复制 StringBuilder 值,因为它会缓存基础数据。
  • 如果要共享 StringBuilder 值,请使用指向它的指针。

解决方法

在 Go 中,astring是一种原始类型,这意味着它是只读的,每次对其进行操作都会创建一个新字符串。

因此,如果我想在不知道结果字符串长度的情况下多次连接字符串,那么最好的方法是什么?

天真的方法是:

var s string
for i := 0; i < 1000; i++ {
    s += getShortStringFromSomewhere()
}
return s

但这似乎不是很有效。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...