弑天下
您只能使用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上尝试):xaaxxaaxyxyxyabc