Maison >développement back-end >Golang >Comment gérer correctement la libération des ressources avec « différer » dans Go Loops ?

Comment gérer correctement la libération des ressources avec « différer » dans Go Loops ?

Linda Hamilton
Linda Hamiltonoriginal
2024-12-22 18:58:10769parcourir

How to Properly Manage Resource Release with `defer` in Go Loops?

Libérer correctement les ressources avec report dans les boucles

Dans les opérations de base de données, il est essentiel de libérer les ressources après utilisation pour garantir l'absence de fuite de mémoire ou de ressources système se produire. Lorsque vous utilisez des instructions defer dans des boucles, il est crucial de comprendre comment l'exécution de ces fonctions est gérée.

Selon la spécification Go, les fonctions différées s'exécutent lorsque la fonction englobante revient ou panique. Par conséquent, si les ressources sont allouées dans une boucle et que le report est utilisé pour les libérer, les ressources ne seront libérées qu'une fois la boucle terminée.

Pour éviter de retarder inutilement la libération des ressources, il est recommandé d'envelopper l'allocation des ressources et libérer le code dans une fonction distincte. Cela garantit que les ressources sont libérées dès qu'elles ne sont plus nécessaires, même en cas de panique :

for rows.Next() {
    func() {
        fields, err := db.Query(...)
        if err != nil {
            // Handle error and return
            return
        }
        defer fields.Close()

        // do something with `fields`
    }()
}

Cette approche garantit que les ressources sont libérées rapidement et le seront toujours même si la boucle englobante rencontre une erreur ou panique. Il est également possible de gérer les erreurs plus gracieusement en les renvoyant depuis la fonction anonyme :

func foo(rs *db.Rows) error {
    fields, err := db.Query(...)
    if err != nil {
        return fmt.Errorf("db.Query error: %w", err)
    }
    defer fields.Close()

    // do something with `fields`
    return nil
}

Ensuite, vous pouvez appeler la fonction depuis la boucle et la terminer à la première erreur :

for rows.Next() {
    if err := foo(rs); err != nil {
        // Handle error and return
        return
    }
}

De plus, si vous souhaitez vérifier l'erreur renvoyée par Rows.Close(), vous pouvez utiliser une autre fonction anonyme :

func foo(rs *db.Rows) (err error) {
    fields, err := db.Query(...)
    if err != nil {
        return fmt.Errorf("db.Query error: %w", err)
    }
    defer func() {
        if err = fields.Close(); err != nil {
            err = fmt.Errorf("Rows.Close() error: %w", err)
        }
    }()

    // do something with `fields`
    return nil
}

En suivant ces Grâce aux meilleures pratiques, vous pouvez garantir une libération appropriée des ressources dans les boucles à l'aide d'instructions defer, évitant ainsi toute fuite potentielle de mémoire ou de ressources tout en gérant efficacement les erreurs.

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:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn