Maison  >  Article  >  développement back-end  >  L'utilisation de Goldmark pour attacher ChildNode dans Golang provoque un débordement de pile

L'utilisation de Goldmark pour attacher ChildNode dans Golang provoque un débordement de pile

PHPz
PHPzavant
2024-02-08 20:42:11942parcourir

在 golang 中使用 Goldmark 附加 ChildNode 会导致堆栈溢出

Contenu de la question

J'utilise Goldmark en Go et je suis nouveau dans ce domaine, donc je ne suis pas sûr de le faire correctement. J'ai lu la documentation, mais je ne comprends pas pourquoi cela se produit.

J'ai analysé un fichier markdown et utilisé ast.walk pour parcourir l'ast.

Mon objectif est d'injecter une sous-liste sous l'élément de liste.

ast.walk(doc, func(n ast.node, entering bool) (ast.walkstatus, error) {
    if entering {
        if n.kind() == ast.kindlistitem {
            sublist := ast.newlist(0)
            sublistitem := ast.newlistitem(0)
            sublist.appendchild(sublist, sublistitem)

            leaf := ast.newstring([]byte("hello"))
            sublistitem.appendchild(sublistitem, leaf)
            n.appendchild(n, sublist)
        }
    }

    return ast.walkcontinue, nil
})

Cependant, lorsque je lance ceci, j'obtiens

runtime: goroutine stack exceeds 1000000000-byte limit
runtime: sp=0xc04f9803c8 stack=[0xc04f980000, 0xc06f980000]
fatal error: stack overflow

Je pense que cela est dû à l'ajout d'un nouveau nœud et à l'accès à ce nœud lors de la prochaine itération. Mais je ne sais pas vraiment comment ignorer les nouveaux nœuds.


Bonne réponse


Vous avez raison, l'erreur de débordement de pile est causée par l'accès d'un nouveau nœud.

Pour résoudre ce problème, vous pouvez enregistrer les nœuds ajoutés et les ignorer dans la fonction walk.

// for recording the added nodes
added := make(map[*ast.List]bool)

ast.Walk(doc, func(n ast.Node, entering bool) (ast.WalkStatus, error) {
    if entering {
        if n.Kind() == ast.KindList {
            if _, ok := added[n.(*ast.List)]; ok {
                // skip the added node
                return ast.WalkSkipChildren, nil
            }
        }
        if n.Kind() == ast.KindListItem {
            subList := ast.NewList(0)
            subListItem := ast.NewListItem(0)
            subList.AppendChild(subList, subListItem)

            leaf := ast.NewString([]byte("Hello"))
            subListItem.AppendChild(subListItem, leaf)
            n.AppendChild(n, subList)

            // record the added node
            added[subList] = true
        }
    }

    return ast.WalkContinue, nil
})

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer