为了账号安全,请及时绑定邮箱和手机立即绑定

我可以使用 make 或 new 在 golang 中制作预填充字符串吗?

我可以使用 make 或 new 在 golang 中制作预填充字符串吗?

Go
呼唤远方 2023-03-29 15:28:42
我正在尝试在 Go 中优化我的 stringpad 库。到目前为止,我发现用已知字符值(例如 0 或“”)填充字符串(实际上是 bytes.Buffer)的唯一方法是使用 for 循环。代码片段是:// PadLeft pads string on left side with p, c timesfunc PadLeft(s string, p string, c int) string {    var t bytes.Buffer    if c <= 0 {        return s    }    if len(p) < 1 {        return s    }    for i := 0; i < c; i++ {        t.WriteString(p)    }    t.WriteString(s)    return t.String()}我相信 string pad 越大,t 缓冲区的内存副本就越多。有没有更优雅的方法来制作一个已知大小的缓冲区,并在初始化时使用已知值?
查看完整描述

1 回答

?
弑天下

TA贡献1818条经验 获得超7个赞

您只能使用make()new()分配已清零的缓冲区(字节片或数组)。您可以使用复合文字来获取最初包含非零值的切片或数组,但您不能动态描述初始值(索引必须是常量)。

从类似但非常有效的strings.Repeat()函数中获取灵感。它以给定的计数重复给定的字符串:

func Repeat(s string, count int) string {

    // Since we cannot return an error on overflow,

    // we should panic if the repeat will generate

    // an overflow.

    // See Issue golang.org/issue/16237

    if count < 0 {

        panic("strings: negative Repeat count")

    } else if count > 0 && len(s)*count/count != len(s) {

        panic("strings: Repeat count causes overflow")

    }


    b := make([]byte, len(s)*count)

    bp := copy(b, s)

    for bp < len(b) {

        copy(b[bp:], b[:bp])

        bp *= 2

    }

    return string(b)

}

strings.Repeat()进行一次分配以获得工作缓冲区(这将是一个字节 slice []byte),并使用内置copy()函数复制可重复的字符串。值得注意的一件事是它使用工作副本并尝试逐步复制整个副本,这意味着例如如果字符串已被复制 4 次,则复制此缓冲区将使其成为 8 次,等等。这将最大限度地减少对copy(). 该解决方案还利用了copy()可以从 a 复制字节string而无需将其转换为字节片的优势。

我们想要的是类似的东西,但我们希望将结果添加到字符串之前。

我们可以考虑到这一点,只需分配一个内部使用的缓冲区Repeat()加上我们左填充的字符串的长度。

结果(不检查参数count):

func PadLeft(s, p string, count int) string {

    ret := make([]byte, len(p)*count+len(s))


    b := ret[:len(p)*count]

    bp := copy(b, p)

    for bp < len(b) {

        copy(b[bp:], b[:bp])

        bp *= 2

    }

    copy(ret[len(b):], s)

    return string(ret)

}

测试它:


fmt.Println(PadLeft("aa", "x", 1))

fmt.Println(PadLeft("aa", "x", 2))

fmt.Println(PadLeft("abc", "xy", 3))

输出(在Go Playground上尝试):


xaa

xxaa

xyxyxyabc


查看完整回答
反对 回复 2023-03-29
  • 1 回答
  • 0 关注
  • 96 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信