Golang中strings.SplitAfter为何会产生额外的空切片元素?

Golang中strings.SplitAfter为何会产生额外的空切片元素? 以下代码中 strings.SplitAfter 的行为是预期的吗? 我原本期望(并且认为这样更有帮助)它只返回 2 个切片元素? 如果这是个简单愚蠢的问题,请见谅,但我似乎找不到类似的问题或明确的答案。

谢谢

package main

import "fmt"
import "strings"

func main() {
    text := "line0\nline1\n"
    lines := strings.SplitAfter(text, "\n")
    fmt.Println(len(lines))
}

3

程序退出。


更多关于Golang中strings.SplitAfter为何会产生额外的空切片元素?的实战教程也可以访问 https://www.itying.com/category-94-b0.html

4 回复

谢谢大家,我明白了,即使分隔符后面没有任何字符串可以成为子字符串,那个帮助片段也可以那样解释。我会记住要调整那个差一错误,GO 语言通常在这方面很友好,能帮助我们避免这类问题,或者我会尝试像你建议的那样做。干杯

更多关于Golang中strings.SplitAfter为何会产生额外的空切片元素?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


SplitAfter 将字符串 s 在每个 sep 实例之后进行切片,并返回这些子字符串的切片。

因此,从这段代码片段来看,我期望得到一个包含 line0line1 的切片,两者都以换行符结尾,并且还有一个第三个空字符串,因为这是原始字符串中第二个换行符之后的内容。

另外,如果你只想得到 ["line0\n" "line1\n"],可以将 strings.SplitAfter 的结果传递给如下函数:

func removeEmptyStringsInplace(ss []string) []string {
	for i := len(ss) - 1; i >= 0; i-- {
		if ss[i] == "" {
			copy(ss[i:], ss[i+1:])
			ss = ss[:len(ss)-1]
		}
	}
	return ss
}

该函数会移除传入切片中的所有空字符串。

在 Go 中,strings.SplitAfter 的行为是符合预期的。根据其文档说明,SplitAfter 会在每个分隔符之后进行分割,并返回所有子字符串的切片。如果原始字符串以分隔符结尾,那么最后一个元素会是一个空字符串。

在你的例子中:

text := "line0\nline1\n"

字符串以 \n 结尾,因此分割后会产生三个元素:

  1. "line0\n"
  2. "line1\n"
  3. ""

你可以通过以下代码验证:

package main

import (
    "fmt"
    "strings"
)

func main() {
    text := "line0\nline1\n"
    lines := strings.SplitAfter(text, "\n")
    fmt.Println(len(lines)) // 输出 3
    for i, line := range lines {
        fmt.Printf("lines[%d] = %q\n", i, line)
    }
}

输出:

3
lines[0] = "line0\n"
lines[1] = "line1\n"
lines[2] = ""

如果你不想要末尾的空字符串,可以使用 strings.TrimSuffix 先去除末尾的分隔符:

package main

import (
    "fmt"
    "strings"
)

func main() {
    text := "line0\nline1\n"
    trimmedText := strings.TrimSuffix(text, "\n")
    lines := strings.SplitAfter(trimmedText, "\n")
    fmt.Println(len(lines)) // 输出 2
    for i, line := range lines {
        fmt.Printf("lines[%d] = %q\n", i, line)
    }
}

或者使用 strings.Split(它不会在分隔符后分割,行为略有不同):

lines := strings.Split(text, "\n")
// 注意:如果 text 以 \n 结尾,这里也会产生空字符串
回到顶部