defer 원리, 성능, 최적화

1620 단어

1. defer 실행 시기

for i:=1;i<10;i++{
    defer log.Println(i)
}

위의 간단한 코드는 기본적으로 여러 defer의 실행 순서를 설명할 수 있다
코드에 defer가 나타날 때, defer가 실행할 함수를 창고에 넣고, 함수가 실행된 후에 defer 창고의 내용을 실행합니다
go1.13 이전에 무더기로 분배하여 체인 테이블에 넣고 나중에 호출, go1.13 창고에 분배하고 defer가 너무 많으면 더미 위에서 체인 테이블로 관리합니다
go1.14는 한층 더 최적화를 했고 defer의 비용은 기본적으로 매우 적다.

2. defer의 평가 시간


defer의 값 부여 조작은 값을 지연시키는 것이 아니라 문장 순서에 따라 값을 부여하는 것이다
다음과 같습니다.
//defer                     
func f3(j int) (i int)  {


	defer func(a int) {
		i += a
		log.Println("------------",j) //    j=100     j=10 a=10
	}(j)

	j =100   //defer         
	return
}

하면, 만약, 만약...
f3(10)

a의 값은 10이고, 인쇄된 j는 마지막에 100으로 인쇄된다
defer는 진입 단계와 퇴출 단계로 나뉜다
다음 예를 보겠습니다.
func f4(j int) (i int)  {

	j =100   //defer         
	defer func(a int) {
		i += a
	}(j)

	return
}

a=100

3. defer 메모리 유출 방지


아래의 이 코드는 메모리 창고를 심각하게 점용하여 짧은 메모리 누출을 초래하여 대량의 파일 핸들이 방출되지 않았다
//    
 func writeManyFiles(files []os.File) error {
	 for _, file := range files {

         defer file.Close()

	 }
	 return nil
 }

함수로 싸인 후 순환할 때마다 파일 핸들을 닫습니다
//      
 func writeManyFiles(files []os.File) error {
	 for _, file := range files {

	 	if err:= func() error {
			f, err := os.Open(file)
			defer f.Close()
			if err != nil {
				return err
			}else {
				return nil
			}
		}();err!=nil{
			return err
		}

	 }
	 return nil
 }

좋은 웹페이지 즐겨찾기