go 中无需双循环:利用 slice 的动态扩容特性高效处理字符筛选
在 Python 中,列表(list)天然支持动态增长,append() 可以无负担地添加元素;初学 Go 的开发者常误以为 slice 是“固定长度的数组”,从而写出先遍历计数、再分配切片、最后二次遍历填充的冗余代码。实际上,Go 的 slice 正是为这种场景设计的动态抽象层——它底层由数组支撑,但通过 len、cap 和 append 提供了类似 Python 列表的弹性行为。
以下是你原始逻辑的更符合 Go 习惯的重构版本(单循环 + append):
func removeAndIndexPunctuation(word string) (string, []rune, []int) { var punctuations []rune var indexes []int var result []rune // 用于构建去标点后的字符串 for i, char := range word { if unicode.IsPunct(char) { punctuations = append(punctuations, char) indexes = append(indexes, i) } else { result = append(result, char) } } return string(result), punctuations, indexes }
✅ 优势说明:
⚠️ 注意事项:
总结:Go 的 slice 不是 C 风格静态数组,而是具备自动增长能力的动态序列抽象。拥抱 append、信任运行时扩容机制,是写出简洁、高效、地道 Go 代码的关键一步——你不需要为“动态性”付出双循环的代价。