Maison  >  Article  >  développement back-end  >  Introduction détaillée aux principales fonctionnalités de Defer dans Golang

Introduction détaillée aux principales fonctionnalités de Defer dans Golang

巴扎黑
巴扎黑original
2017-08-12 14:41:561385parcourir

defer est un mot-clé du langage golang, qui est utilisé pour libérer des ressources et sera appelé avant le retour de la fonction. L'article suivant vous présente principalement les principales fonctionnalités de defer dans Golang. L'article le présente en détail à travers un exemple de code, qui a une certaine valeur de référence et d'apprentissage pour tous les amis qui en ont besoin peuvent y jeter un œil ci-dessous.

Préface

Tout le monde connaît le mot-clé defer de golang, qui peut effectuer certaines opérations avant le retour de la fonction. La plus couramment utilisée est d'ouvrir un fichier. Lorsque vous utilisez une ressource (comme un fichier, une connexion à une base de données, etc.), utilisez defer pour retarder la fermeture de la ressource afin d'éviter les fuites de mémoire. Cet article vous présente principalement les principales fonctionnalités de Defer dans Golang et le partage pour votre référence et votre étude. Sans plus tarder, jetons un coup d'œil à l'introduction détaillée :

1. defer Le rôle et le moment d'exécution de l'instruction defer de

go sont utilisés pour retarder l'exécution des fonctions, et le retard se produit après l'appel du retour de fonction, comme


func a() int {
 defer b()
 return 0
}

L'exécution de b se produit après le retour 0. Faites attention à la syntaxe de defer Le mot-clé defer est suivi de l'appel de fonction.

2. Utilisations importantes du report 1 : Nettoyer et libérer les ressources

En raison de la caractéristique de retard du report, le report est souvent utilisé à la fin d'un appel de fonction. Ensuite, nettoyez les ressources associées, telles que


f, _ := os.Open(filename)
defer f.Close()

La libération des ressources du fichier sera automatiquement exécutée à l'aide de defer. une fois l'appel de fonction terminé, il n'est pas nécessaire de se rappeler à tout moment où les ressources doivent être libérées, l'ouverture et la libération doivent correspondre.

Utilisez un exemple pour expliquer en profondeur la commodité et la simplicité apportées par le report.

Le but principal du code est d'ouvrir un fichier puis de copier le contenu dans un autre nouveau fichier. Sans tarder, écrivez comme ceci :


func CopyFile(dstName, srcName string) (written int64, err error) {
 src, err := os.Open(srcName)
 if err != nil {
  return
 }
 dst, err := os.Create(dstName)
 if err != nil { //1
  return
 }
 written, err = io.Copy(dst, src)
 dst.Close()
 src.Close()
 return
}
<.> Une fois le code renvoyé au n° 1, le fichier src n'est pas fermé, ce qui peut empêcher la libération correcte des ressources : utilisez plutôt defer :


func CopyFile(dstName, srcName string) (written int64, err error) {
 src, err := os.Open(srcName)
 if err != nil {
  return
 }
 defer src.Close()
 dst, err := os.Create(dstName)
 if err != nil {
  return
 }
 defer dst.Close()
 return io.Copy(dst, src)
}
. src et dst Il peut être nettoyé et publié à temps, quel que soit l'endroit où le retour est exécuté.

Compte tenu du rôle du defer, le defer est souvent utilisé pour libérer des connexions à une base de données, des handles d'ouverture de fichiers et d'autres opérations pour libérer des ressources.

3. Utilisations importantes de defer 2 : exécuter recovery

La fonction différée est exécutée après le retour. La panique déclenchée par une fonction peut être capturée, donc une autre utilisation importante du report est d'effectuer une récupération.

recover n'est que plus significatif lorsqu'il est utilisé en mode différé. Si elle est utilisée ailleurs, l'erreur ne peut pas être efficacement capturée car le programme a déjà été appelé et revient plus tôt.


package main
import (
 "fmt"
)
func main() {
 defer func() {
  if ok := recover(); ok != nil {
   fmt.Println("recover")
  }
 }()
 panic("error")
}
N'oubliez pas que le report doit être placé avant l'exécution de panique.

4. La séquence d'exécution de plusieurs reports

La fonction de defer est de pousser l'exécution de la fonction après le mot-clé dans un stack Exécution retardée moyenne, l'ordre d'exécution de plusieurs reports est LIFO :


defer func() { fmt.Println("1") }()
defer func() { fmt.Println("2") }()
defer func() { fmt.Println("3") }()
L'ordre de sortie est 321.

Cette fonctionnalité peut implémenter une opération d'ordre inverse sur un tableau.

5. Les paramètres de la fonction différée sont déterminés lors du report

C'est la caractéristique du report. defer, Ses paramètres sont calculés et déterminés lorsqu'ils sont différés. Même si les paramètres sont modifiés après le report, cela n'aura aucun effet sur la fonction qui a été différée. Regardez l'exemple :


func a() {
 i := 0
 defer fmt.Println(i)
 i++
 return
}
a La sortie de l'exécution est 0 au lieu de 1, car en cas de report, la valeur de i est 0 et les paramètres de la fonction sont différés ont déjà été traités. Les calculs ont été effectués et confirmés.

Regardez un autre exemple :


func calc(index string, a, b int) int {
 ret := a + b
 fmt.Println(index, a, b, ret)
 return ret
}
func main() {
 a := 1
 b := 2
 defer calc("1", a, calc("10", a, b))
 a = 0
 return
}
Sortie du code d'exécution


10 1 2 3 
1 1 3 4
Le troisième paramètre de la fonction de report a été calculé et déterminé au moment du report, et il en va de même pour le deuxième paramètre a. Cela n'affecte pas si la variable a est modifiée ultérieurement.

6. La fonction différée peut lire et modifier la valeur de retour avec le nom


func c() (i int) {
 defer func() { i++ }()
 return 1
}
La fonction différée est exécutée après le retour et la valeur de retour avec le nom peut être modifiée. La fonction c ci-dessus renvoie 2.

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