golang - 在递归函数运行期间,切片中指针的内容会发生变化

时间:2016-02-16 18:44:24

标签: 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之后,我检查了matchDiv切片的内容,然后让函数再次递归调用自身。然后在if append的下方,该函数递归调用一次。然后我停在fmt.Println(htmlTag.Class)并再次查看matchingDivs切片的内容。内容与以前完全不同。

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

1 个答案:

答案 0 :(得分:1)

tag变量在循环开始时声明一次,并且每次迭代都会覆盖tag的值。这与您在FAQ中看到的问题相同:"What happens with closures running as goroutines?"

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

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

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

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