Maison >développement back-end >Golang >Passer le pointeur pour aller différer la fonction ne fonctionne pas

Passer le pointeur pour aller différer la fonction ne fonctionne pas

WBOY
WBOYavant
2024-02-13 12:24:09692parcourir

将指针传递给 go defer 函数不起作用

En programmation PHP, le pointeur peut ne pas fonctionner lorsqu'il est passé à la fonction go defer. Les pointeurs en PHP sont utilisés pour stocker l'adresse mémoire des variables. En passant le pointeur, la valeur de la variable d'origine peut être modifiée à l'intérieur de la fonction. Cependant, lors du passage d'un pointeur vers une fonction go defer, il arrive parfois que la variable d'origine ne puisse pas être modifiée. Cela peut être dû au fait que la fonction go defer crée un nouveau Goroutine lors de son exécution et que le pointeur peut pointer vers un espace mémoire différent, ce qui entraîne l'échec de la modification correcte de la valeur de la variable. Par conséquent, dans la programmation PHP, les pointeurs doivent être passés pour différer les fonctions avec prudence afin d'éviter des problèmes inattendus.

Contenu de la question

Dans mon code, j'essaie d'utiliser numaddr pour enregistrer le changement de num après l'instruction defer

func deferrun() {
    num := 1
    numaddr := &num
    defer fmt.printf("num is %d", *numaddr)
    num = 2
    return
}

func main() {
    deferrun()
}

Mais j'obtiens la valeur de num 是 1 而不是 2,为什么 defer 函数使用 *numaddr au lieu de l'adresse ?

Alors je vais essayer une autre méthode

func deferRun() {
    num := 1
    numAddr := &num
    defer func(intAddr *int){
        fmt.Printf("num is %d", *numAddr)
    }(numAddr)
    
    num = 2
    fmt.Println("num is", *numAddr)
    return
}

func main() {
    deferRun()
}

Cette fois, ça marche, j'obtiens num 是 2,所以我想也许 defer fmt.printf(something) La chaîne est stockée immédiatement lors de sa déclaration et le numaddr n'est pas utilisé lorsque la fonction defer s'exécute réellement ?

Solution

Question intéressante. Pour répondre à cette question, vous devez connaître une règle, comme ce tutoriel go https://go.dev/tour/flowcontrol/12

延迟调用的参数会立即计算,但直到周围函数返回时才会执行函数调用。.

Exemple 1 : Dites à la fonction defer d'imprimer la valeur située à l'adresse mémoire spécifiée.

func deferrun() {
    num := 1
    numaddr := &num //address of variable num in stack memory, 0xc000076f38 for example
    defer func(intaddr *int){
        fmt.printf("num is %d", *numaddr)
    }(numaddr) //hey go, when the surrounding function returns, print the value located in this address (numaddr=0xc000076f38)
    num = 2 //now the value located in address 0xc000076f38 is 2
    return  
}

La sortie sera 2.

Exemple 2 : Dites à la fonction defer d'imprimer la valeur spécifiée.

func deferRun() {
    num := 1
    numAddr := &num //address of variable num in stack memory, 0xc000076f38 for example
    defer fmt.Printf("num is %d", *numAddr) //Hey Go, when the surrounding function returns, print the this value *numAddr (*numAddr is 1 for now)
    num = 2 //Now the value located in address 0xc000076f38 is 2 but you told the defer function to print 1 before
    return  
}

La sortie sera 1.

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