在运行时填充长度设置的切片时,我是否绝对需要两个循环,一个用于确定长度,一个用于填充?

When populating a slice with length set at runtime, do I absolutely need two loops, one for determining the length and one for populating?

所以我有一个函数可以从字符串中删除标点符号并将这些标点符号字符及其索引放入两个切片中:

func removeAndIndexPunctuation(word string) (string, []rune, []int) {
    // Index punctuation
    numberOfPunct := 0
    for _, char := range word {
        if unicode.IsPunct(char) {
            numberOfPunct += 1
        }
    }

    punctuations := make([]rune, numberOfPunct)
    punctuationIndex := make([]int, numberOfPunct)

    x := 0
    for i, char := range word {
        if unicode.IsPunct(char) {
            punctuations[x] = char
            punctuationIndex[x] = i
            x += 1
        }
    }

    // Remove all punctuation from word string
    res := r.ReplaceAllString(word, "")
    return res, punctuations, punctuationIndex
}

为了制作和填充切片,我必须 运行 两个 for 循环,一个用于计算标点符号的数量,这样我就可以使数组的长度正确,另一个几乎相同,除了现在我填充切片。

在 Python 中,虽然我不需要两个 for 循环,因为 Python 支持 "dynamic arrays":

def removeAndIndexPunctuation(word):
    punctuations = []
    # Index punctuation
    for i, char in enumerate(word):
        if char in string.punctuation:
            punctuations.append((char, i))
    # Remove all punctuation from word string
    word = word.encode("utf-8").translate(None, string.punctuation).decode("utf-8")
    return word, punctuations

所以我只想确定,在这种情况下,在 golang 中,我是否绝对需要两个 for 循环,因为它不支持动态数组,或者我是否遗漏了什么?或者换句话说,如果我循环遍历一组字符并将一些字符添加到 array/slice,我真的需要两个循环,一个用于计算设置切片长度的字符数,另一个用于填充切片?

我来自Python,正在学习围棋。

你不知道。 Golang 切片是动态数组(不要将它们与实际数组混淆)。您应该(重新)阅读关于它的优秀 golang slice internals 博客 post。

这是您以更惯用的方式重写的示例:

func removeAndIndexPunctuation(word string) (string, []rune, []int) {
    var punctuations []rune
    var indexes []int

    for i, char := range word {
        if unicode.IsPunct(char) {
            punctuations = append(punctuations, char)
            indexes = append(indexes, i)
        }
    }

    // Remove all punctuation from word string
    res := r.ReplaceAllString(word, "")
    return res, punctuations, indexes
}

请注意,我认为 regex 的使用在这里不是特别相关。这是另一个使用符文片段的版本:

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
}