一尘不染

golang-切片中指针的内容在递归函数运行期间发生更改

go

func getAllCertainDivs(className string, idName string, htmlTag *HtmlTag, matchingDivs *[]*HtmlTag) {
    fmt.Println(htmlTag.Class)
    if htmlTag.XMLName.Local == "div" {
        if htmlTag.Class == className && htmlTag.Id == idName {
            *matchingDivs = append(*matchingDivs, htmlTag)
        }
    }

    for _, tag := range htmlTag.ChildTags {
        getAllCertainDivs(className, idName, &tag, matchingDivs)
    }
}

如您所见,在上面的函数中,我将切片的指针传递给该getAllCertainDivs函数。在某一点HtmlTag上将指针推入切片中matchingDivs。之后append,在让函数再次递归调用自身之前,我检查matchingDiv切片的内容。然后在if所在的位置append下,该函数递归调用一次。然后我停在fmt.Println(htmlTag.Class)matchingDivs再次检查切片的内容。而且内容与以前完全不同。

只有一种append,内容如何改变?每次我将其传递到下一个递归调用时,是否golang使用相同的HtmlTag指针?


阅读 191

收藏
2020-07-02

共1个答案

一尘不染

tag变量在循环开始时声明一次,tag每次迭代都会覆盖的值。这是与在FAQ中看到的相同问题:“以goroutine运行闭包会发生什么?”

您可以在每次迭代期间声明一个新变量,以获取函数调用的唯一指针:

for _, tag := range htmlTag.ChildTags {
    tag := tag
    getAllCertainDivs(className, idName, &tag, matchingDivs)
}

或者,您可以忽略范围值,并直接使用索引:

for i := range htmlTag.ChildTags {
    getAllCertainDivs(className, idName, &htmlTag.ChildTags[i], matchingDivs)
}
2020-07-02