Go lang - 9 : defer 와 패닉

개발조아·2022년 3월 26일
0

go-lang

목록 보기
9/13

패닉

해당 라인까지만 실행되는 에러로 실행 중에 기능을 중단시킨다.
단, 패닉이 발생되면 작성된 defer 를 역순으로 먼저 실행하고 패닉처리됩니다.

defer + 함수

찾아보면 defer 에 대해서 잘 정리된 글들이 많이 있다.
내가 이해한 바로는 해당 함수의 코드실행을 지연시키고(거꾸로 실행하도록)
반드시 실행하게 만든다.

File 을 가져오는 부분을 아래 내용으로 구현해보자!
1. 파일을 읽었는데 비어있으면 error 발생 -> 파일을 닫아줘야함(defer 처리)
2. 파일의 라인이 "error" 면 panic 발생(강제 에러만들기) -> 파일 닫아줘야함
3. 파일이 이미 닫혔지만 또 닫아서 defer 끼리 error 가 발생하면 다른 defer 가 실행되는지 확인해보자 !!

package main

import (
	"bufio" // buffered I/O 관련 패키지
	"fmt"
	"os" // 우리가 아는 그 OS (운영체제) 관련 패키지
)

func main() {
	fo, err := os.Open("test.txt")

	if err != nil {
		panic(err) // 파일이 없다면 panic (에러) 출력
	}

	defer func(fo *os.File) { // defer 에서도 예외를 처리해준다.
		err := fo.Close()
		if err != nil {
			panic(err) // 실패로 인해 줄력됨
			return
		}
	}(fo)

	defer fo.Close() // 미리 종료해보기 => 실패

	defer func(fo *os.File) { // 미리 종료해보기 => 성공
		err := fo.Close()
		if err != nil {
			panic(err)
			return
		}
	}(fo)

	reader := bufio.NewReader(fo) // 기본 크기가 있는 새 Reader 를 반환해줍니다.
	for {
		line, isPrefix, err := reader.ReadLine()
		// 저 수준으로 해당 줄을 바이트로 => line
		// 해당 줄 크기가 담고있는 버퍼보다 크면 isPrefix 가 True 가 됩니다.
		// err 는 에러
		if isPrefix || err != nil {
			break
		}
		if string(line) == "error" {
			panic("error panic")
		}
		fmt.Println(string(line))
	}
}

파일 ./test.txt

파일 내용

테스트1
test2
test three
error

Console

결론

defer 끼리 panic 이 발생해도 실행된다.

하지만 아에 그 라인을 읽기 전 부터 패닉이 발생되면 읽지 못한다.
이유 : 패닉이 발생되면 해당 패닉 위 라인의 defer 만 실행됨

profile
https://github.com/askePhoenix

0개의 댓글