한 눈에 끝내는 고랭 기초
    • 01
      시작하기에 앞서
    • 강의대상
      Go란?
      실습 환경 구축 - 구름IDE
      Hello goorm! 출력해보기
    • 02
      변수와 상수
    • 콘솔 출력 함수의 기본
      변수의 선언과 초기화
      상수의 선언과 초기화
      간단한 덧셈
      잘못된 신상정보
    • 03
      연산자
    • 연산자 종류
      연산자 우선순위
      콘솔 입력 함수의 기본
      간단한 덧셈과 곱셈
      몫과 나머지
    • 04
      자료형
    • 자료형의 종류와 특징
      문자열의 표현
      자료형의 변환
      강제 형 변환
    • 05
      콘솔 출력과 입력 함수
    • 콘솔 출력 함수(Print)
      콘솔 입력 함수(Scan)
      정돈된 표
      신상정보 입력과 출력
    • 06
      반복문 - for
    • 오로지 for
      구구단
      빛나는 이등변삼각형
    • 07
      조건문 - if/else
    • 조건에 따른 실행과 흐름 분기
      7과 9의 배수
      두 수의 차
    • 08
      분기문 - switch
    • swich문에 의한 선택적 실행
      안좋은 계산기
    • 09
      제어문
    • break, continue, goto문
      구구단2
      두 수를 더하면 99
    • 10
      컬렉션
    • 배열(Array)
      슬라이스(Slice)
      맵(Map)
      역행렬
      가장 긴 이름
      중간고사 평균 점수
    • 11
      함수
    • Go언어에서의 함수
      전역변수와 지역변수
      매개변수
      반환값(리턴값)
      익명 함수
      오름차순 정렬
      아이패드를 사주는 조건
      역학적 에너지
    • 12
      클로저
    • 외부 변수 접근 : 클로저
      동전 정리
    • 13
      구조체와 메소드
    • 구조체
      메소드
      성적 저장 프로그램
      역학적 에너지2
    • 14
      인터페이스(interface)
    • 메소드의 집합 인터페이스
      직육면체와 원기둥
    • 15
      defer와 panic()
    • 지연 처리 defer
      종료하는 panic(), 복구하는 recover()
      엘리베이터
      중간고사 평균 점수2
    • 16
      에러 처리
    • 에러 처리의 기본
      에러 출력 및 처리
      중간고사 평균 점수3
    • 17
      고루틴(Goroutine)
    • 비동기 프로세스의 기본
      고루틴의 활용
      고루틴 실습
    • 18
      채널(Channel)
    • 고루틴의 데이터 통로 : 채널
      비동기 채널과 버퍼
      동기 채널
      채널 닫기
      송신 전용, 수신 전용 채널
      채널 select문
      고루틴 실습2
      메시지 전송
      동기 채널 실습
      비동기 채널 실습
    • 19
      패키지(package)
    • 패키지의 개념
    • 20
      실전 프로젝트 - 마일리지 상점
    • 프로젝트를 시작하기 앞서
      실습모드에서 실습
      마일리지 상점의 주요 기능
      필수 구조체와 매인 메뉴
      잔여 수량, 잔여 포인트 구현
    • 21
      실전 프로젝트 - 주문하기, 장바구니 담기
    • 구매 구현(1)
      구매 구현(2)
      장바구니에 담기
      장바구니 확인(1)
      장바구니 확인(2)
    • 22
      실전 프로젝트 - 고루틴으로 배송하기
    • 배송 상태 확인(1)
      배송 상태 확인(2)
      배송 상태 확인(3)
      최종 코드
    종료하는 panic(), 복구하는 recover()
    15 defer와 panic()
    종료하는 panic(), 복구하는 recover()

    지난 강의에서 함수 내에서 가장 마지막에 꼭 실행하는 defer에 대해서 배웠습니다. defer가 선언된 함수는 중간에 프로그램이 에러가 발생하더라도 꼭 마지막에 실행합니다.(에러가 생기는 코드 전에 선언됐을 때) 이는 "끝내기 전에 이거는 실행하고 끝내줘."라는 것과 같습니다. 하지만 이번 강의에서 배울 panic은 상반된 기능을 합니다. panic은 겉으로 보이게 아무런 문제가 없는데 실행해보니 에러가 발생해서 프로그램을 종료하는 기능을 합니다. 반대로 말하자면 문법 자체를 잘못 입력했을 때 발생하는 에러는 panic이 아닙니다.


    여기서 헷갈리는 부분이 있습니다.  "겉으로 보이기에 아무런 문제가 없는데 오류가 발생하는 코드가 무엇이지?" 라고 생각할 수 있습니다. 이것은 바로 '오류'와 '예외'의 차이입니다. 오류는 프로그램상 허용하지 않는 문법과 같은 비정상적인 상황에 발생하는 것을 말합니다. 예를 들어, int형 변수에 30.5를 초기화 하면 오류가 발생합니다. 그리고 예외는 프로그램이 실행되면서 논리상으로 부적합한 상황이 발생하는 것을 말합니다. 예를 들어, 나눗셈을 할 때 10 / 0은 논리적 예외 상황인 것입니다. 따라서 이러한 것들은 프로그램이 오류라고 생각하지 않기 때문에 코드 상에서 따로 예외 처리를 해야합니다.   


    아래는 오류가 발생한 경우와 예외 상황에서 panic이 발생한 경우를 순서대로 보여줍니다. 바로 실행해보세요.

    go
    실행 결과를 확인해보세요!
    go
    실행 결과를 확인해보세요!

    그리고 만약에 panic이 발생한 함수 안에 defer 구문이 있다면 프로그램을 종료하기 전에 defer 구문을 실행하고 종료합니다. 


    아래 panic이 발생하고 프로그램이 종료되기 전에  defer 구문이 실행되는 예시 코드가 있습니다. 바로 실행해보세요.

    go
    실행 결과를 확인해보세요!

    반복문 안에서 선언한 배열의 개수보다 큰 인덱스 값을 접근함으로써 panic이 발생하고 프로그램이 종료됩니다. 하지만 defer fmt.Println("Panic done") 구문이 panic 에러가 발생하는 코드 전에 선언되었기 때문에 프로그램이 종료되기 전에 "Panic done"이 출력되고 종료됩니다. 따라서 main() 함수에 있는 fmt.Println("Hello, world!")는 실행되지 않습니다.(panic이 발생해 프로그램이 종료돼서)


    또한, panic은 에러뿐만 아니라 사용자가 panic() 함수를 이용해 예외 상황일때(아무때나 사용할 수 있지만) 직접 panic 에러를 발생시킬수 있습니다. 여기서 panic() 함수 안에 에러 메시지를 사용자 설정으로 출력할 수 있습니다. 조건문 강의에서 사용했던 예시 코드를 활용해보겠습니다.


    아래 코드를 바로 실행해보세요.

    go
    실행 결과를 확인해보세요!

    이렇게 panic() 함수는 프로그램 흐름에서 에러로 처리하고 싶은 부분에 개발자의 설정으로 사용할 수 있습니다. 

    위 코드는 범위에 벗어난 숫자를 입력했을 때 panic() 함수를 호출해 에러를 발생시켜 프로그램을 종료합니다. 예시는 예시일 뿐, 숫자를 잘못 입력했다고 프로그램을 종료시키도록 프로그램을 제작하는 개발자는 없을 것이라고 생각합니다. 


    panic을 막는 recover() 함수


    위 예시에서 언급했듯이 에러가 생기는 상황에 바로 panic을 발생시키고 프로그램을 종료하는 것은 안 좋은 방법이 될 수 있습니다. 그렇다면 에러가 생기는 상황만 예외 처리를 하면 어떨까요? Java에서는 try ~catch 구문을 사용해 이러한 예외 처리를 하는데 recover() 함수도 이와 같은 역할을 한다고 생각하면 됩니다. panic 상황이 생겼을 때 프로그램을 종료하지 않고 예외 처리를 하는 것입니다. panic() 함수와 recover() 함수를 사용해  프로그램 흐름을 사용자가 미리 예외처리를 할 수 있는데 위에서 언급한 것처럼 panic 상황에서 프로그램이 종료되지 않고 어떤 구문을 실행시키려면 defer 구문을 사용해야합니다. 따라서 예외 처리를 하기 위해서는 recover() 함수와 defer 구문을 항상 같이 사용해야합니다.


    아래 위에서 살펴본  index out of range에러를 발생하는 코드를 recover() 함수를 사용해 예외 처리를 한 예시 코드가 있습니다.

    go
    실행 결과를 확인해보세요!

    위 코드에서 제일 눈에 띄는 것은 panic이 발생하는 코드 전에 defer 구문을 사용한 익명 함수로 recover() 함수를 선언해놓은 것입니다. 따라서 for문에서 index out of range panic이 발생해 프로그램이 종료 되기 전에 지연 처리한 defer 익명 함수가 호출되고 익명 함수 내에 recover() 함수가 호출되면서 panic을 복구합니다. 따라서 프로그램이 그냥 종료되지 않고 main() 함수에서 선언한 fmt.Println("Hello, world!")가 호출되어 프로그램이 종료되지 않았다는 것을 증명합니다. panic이 발생한 해당 함수는 종료되고 다음 코드를 실행합니다. 그래서 panicTest() 다음 코드인 fmt.Println("Hello, world!")을 실행한 것입니다.


    쉽게 말해 recover() 함수는

    • panic이 발생해 프로그램이 종료되는 것을 막고 복구합니다.
    • 프로그램이 종료되기 전에 실행되어야 함으로 defer 가 선언된 함수 안에서 쓰입니다.
    • 에러 메시지를 반환합니다. 따라서 변수에 초기화해서 에러 메시지를 출력할 수 있습니다. 변수에 초기화하지 않으면 따로 에러 메시지를 출력하지 않습니다. 

    아래는 중간고사 평균 점수2 실습에 도움이 될만한 예시 코드입니다. 재귀 함수를 이용해 defer 구문에 복구와 동시에 main() 함수를 다시 실행시킵니다.

    go
    실행 결과를 확인해보세요!
    질문하기