Golang defer

3353 단어
화제는 동료가 위챗 커뮤니티에 올린 그림에서 비롯됐다. Go Newsletter가 13일 트위터에 올린 코드 캡처로 출력이 무엇인지 물었다.코드는 다음과 같습니다. 출력 결과는 문장 끝에 있습니다.
package main

import "fmt"

type number int

func (n number) print()   { fmt.Println(n) }
func (n *number) pprint() { fmt.Println(*n) }

func main() {
    var n number

    defer n.print()
    defer n.pprint()
    defer func() { n.print() }()
    defer func() { n.pprint() }()

    n = 3
}

내가 만약 코드를 놓치지 않는다면, 어쨌든 결과를 모를 것이다.뒤에서 트위터에 올라온 댓글을 봤는데 5년 동안 go를 썼는데 이 결과가 될지 모르겠다는 친구가 있었어요. 하하.주말에 틈이 나면 기본적으로 골뱅이 데퍼의 사용법이다.

defer


공식적으로 제시된 문서에서 defer의 집행에는 세 가지 기본 규칙이 있다.
1. defer 함수는 외부 함수return 이후 선집행(창고) 순서에 따라 집행한다.
package main

import "fmt"

func main() {
    defer fmt.Println("1")
    defer fmt.Println("2")
    defer fmt.Println("3")
}

출력
3
2
1

2. defer 함수의 매개 변수의 값은 defer를 설명할 때 확정된 것이다.
몇 가지 예를 보아라, 첫 번째 규칙에 주의해라.이것은 일반적인 유형의 예이다.
package main

import "fmt"

func main() {
    i := 0

    defer fmt.Println(i)  //       defer     
    defer func(j int) { fmt.Println(j) }(i)  //     
    defer func() { fmt.Println(i) }()  //     (closure)    

    i++
}

출력:
1
0
0

인용 유형도 마찬가지다.
4
  • 인용 대상의 속성을 수정할 때:
  • package main
    
    import "fmt"
    
    type Person struct {
        name string
    }
    
    func main() {
        person := &Person{"Lilei"}
    
        defer fmt.Println(person.name)  // person.name        defer     
        defer fmt.Printf("%v
    ", person) // defer func(p *Person) { fmt.Println(p.name) }(person) // defer func() { fmt.Println(person.name) }() // , person.name = "HanMeimei" }

    출력:
    HanMeimei
    HanMeimei
    &{HanMeimei}
    Lilei
    

    4
  • 인용 자체를 수정할 때:
  • package main
    
    import "fmt"
    
    type Person struct {
        name string
    }
    
    func main() {
        person := &Person{"Lilei"}
    
        defer fmt.Println(person.name)  //   ,person.name        defer     
        defer fmt.Printf("%v
    ", person) // defer , “Lilei” defer func(p *Person) { fmt.Println(p.name) }(person) // defer func() { fmt.Println(person.name) }() // , person “HanMeimei” person = &Person{"HanMeimei"} }

    출력:
    HanMeimei
    Lilei
    &{Lilei}
    Lilei
    

    defer 함수를 설명할 때 외부 변수에 대한 인용은 두 가지 방식이 있는데 그것이 바로 함수 매개 변수와 패키지 인용이다.함수 매개 변수로서 defer가 설명할 때 값을 defer에 전달하고cache에 전달합니다.클로즈업으로 인용하면 defer 함수가 실행될 때 전체 상하문에 따라 현재 값을 정합니다.
    3. defer 함수는 외부 함수가 설명한 반환 값을 읽고 수정할 수 있습니다.
    마찬가지로 예를 하나 주다
    package main
    
    import "fmt"
    
    func main() {
        fmt.Printf("output: %d
    ", f()) } func f() (i int) { defer fmt.Println(i) // defer func(j int) { fmt.Println(j) }(i) // defer func() { fmt.Println(i) }() // defer func() { i++ }() // ,i=2 defer func() { i++ }() // ,i=1 i++ return }

    이전의 기초가 있으면 이 출력은 쉽게 추측할 수 있다.
    3
    0
    0
    output: 3
    

    defer의 기본 규칙은 이 세 가지입니다.알고 보니 순식간에 밝아졌다.

    처음


    defer의 세 가지 규칙(사실 앞의 두 가지만)을 통해 출력을 알 수 있습니다.
    3
    3
    3
    0
    

    좋은 웹페이지 즐겨찾기