Maison > développement back-end > Golang > Introduction au go defer (fonction go delay)

Introduction au go defer (fonction go delay)

Libérer: 2019-11-30 14:03:38
avant
2343 Les gens l'ont consulté

Le report du langage Go

Introduction au go defer (fonction go delay)

Go est considéré comme une nouvelle fonctionnalité du langage, du moins par rapport aux langages de programmation traditionnels d'aujourd'hui.

L'instruction defer appelle une fonction. L'exécution de cette fonction sera reportée jusqu'au retour de la fonction périphérique, ou jusqu'à la fin de la fonction périphérique, ou jusqu'à ce que la goroutine correspondante panique

Chaque fois que defer est utilisé. exécuté, il La valeur de la fonction suivante (dans Go, la fonction est un type de référence, un citoyen de première classe et peut être affectée à une variable) et les paramètres de la fonction seront évalués, mais la fonction ne sera appelée immédiatement que (↑ ), les trois situations ci-dessus se produisent. C'est tout le contenu de defer, disparu, le reste est la meilleure pratique de defer

La fonction ne sera pas appelée immédiatement

Commençons par la plus simple :

func readFile(fileName string){
    f,err := os.Open(fileName)
    if err!=nil {
        return
    }
    defer f.Close()
    var content [1024]byte
    f.Read(content[:])
    fmt.Printf("%s",content)
}
func main() {
    readFile("test.data")
}
Copier après la connexion

Le programme génère les 1024 premiers octets de test.data. Il convient de mentionner que les opérations de couplage ouverture/fermeture comme celle-ci sont l'usage idiomatique du report. Cet exemple explique la seconde moitié de la phrase ci-dessus

"Mais la fonction ne sera pas appelée"

Parce que si f.Close() après le defer n'est pas retardé, alors le descripteur de fichier S'ils sont tous fermés, rien ne sera lu.

La valeur de la fonction et les paramètres de la fonction sont évalués, mais la fonction n'est pas appelée immédiatement

L'exemple suivant expliquera la première moitié, il vient de <> , légèrement Modification :

func trace(funcName string) func(){
    start := time.Now()
    fmt.Printf("function %s enter\n",funcName)
    return func(){
        log.Printf("function %s exit (elapsed %s)",funcName,time.Since(start))
    }
}
 
func foo(){
    defer trace("foo()")()
    time.Sleep(5*time.Second)
}
func main(){
    foo()
    foo()
}
/*
OUTPUT:
function foo() enter
function foo() exit (elapsed 5.0095471s)
function foo() enter
function foo() exit (elapsed 5.0005382s)
*/
Copier après la connexion

Pourquoi la sortie foo entre-t-elle puis attend-elle environ cinq secondes avant de sortir la sortie Parce que comme nous l'avons dit, les valeurs et les paramètres de la fonction après

defer seront évalués ? mais la fonction réelle L'appel doit attendre la fin

La valeur de la fonction ici est la fonction anonyme renvoyée par trace(). Le paramètre de la fonction est bien sûr la valeur littérale de la chaîne "foo()". de trace("foo()") la fonction de sortie foo() entrera, l'appel de fonction réel trace("foo()")(), c'est-à-dire que la fonction de sortie foo() exit(elapsed x.x) sera reportée à return exécution (si return mettra à jour la variable de valeur de retour, elle sera exécutée après la mise à jour avant d'exécuter la fonction defer).

Divers

Un petit plus, s'il y a plusieurs instructions defer, l'ordre d'exécution de la dernière fonction defer est opposé à l'ordre dans lequel defer apparaît, comme par exemple :

func main() {
    func1 := func(){
        fmt.Println("func1() execution deferred")
    }
    func2 := func(){
        fmt.Println("func2() execution deferred")
    }
    defer func1()
    defer func2()
    fmt.Println("strat\nworking...")
}
/*
OUTPUT:
strat
working...
func2() execution deferred
func1() execution deferred
*/
Copier après la connexion

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!

Étiquettes associées:
go
source:cnblogs.com
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal