Go 퀴즈에 대해서~ Named return values~

6824 단어 Gotech
이 기사는 DeNA 20 졸업생 Advent Calendar 2020 23일째 보도다.
요즘 유행하는 거?퀴즈 Go 퀴즈 도전!

문제.


다음 실행 결과는 어떻게 될까요?
package main

import "fmt"

func main() {
  run()
}

func run() (err error) {

  defer func() {
    if err != nil {
      fmt.Println(err)
    }
  }()

  if err := fmt.Errorf("Error caught!"); err != nil {
    return
  }

  return
}
  • 컴파일 오류
  • "Error caught!"출력
  • 출력 없음
  • 정답과 해설


    정답
    정답은 1입니다.
    컴파일 오류.
    해설
    이 일은 고의 스펙에 다음과 같이 기술되어 있다.
    Implementation restriction: A compiler may disallow an empty expression list in a "return"statement if a different entity (constant, type, or variable) with the same name as a result parameter is in scope at the place of the return.
    https://golang.org/ref/spec#Return_statements
    함수 내의 다른 역할 영역에서 이름 반환값(Named return values)에 지정된 이름과 같은 변수, 상수, 유형을 선언하고 이 역할 영역에서 빈 반환을 수행합니다.어느 것을 우선해야 할지 모르기 때문에 (함수를 정의하는 역할 영역에서 설명하거나 다른 역할 영역에서 설명하는 것) 컴파일 오류가 발생할 수 있습니다.
    확실히 반대로 어떤 언어를 우선적으로 사용하면 혼란을 초래할 수 있기 때문에 컴파일 오류가 친절하다.
    이 경우 다음과 같은 반환 값을 명시적으로 표시하면 컴파일은 "Error caught"를 통해출력
      if err := fmt.Errorf("Error caught!"); err != nil {
        return err
      }
    
    (참고로 defer는 사람을 현혹시키는 갈고리)

    추가 질문


    Named return values의 말과는 조금 다르지만 다음과 같은 상황을 수행한 결과는 어떻게 되었습니까?
    package main
    
    import "fmt"
    
    func main() {
      run()
    }
    
    func run() error {
    
      var err error
      defer func() {
        if err != nil {
          fmt.Println("Error caught!")
        }
      }()
    
      if err := fmt.Errorf("hoge error"); err != nil {
        return err
      }
    
      return nil
    }
    
    
  • 컴파일 오류
  • "Error caught!"출력
  • 출력 없음
  • 추가 정답 및 설명


    정답
    정답은 3.아무것도 내보내지 않습니다.
    해설
    defer문에서err는var err error의err를 가리키기 때문에if문의 범위 내에서 정의된err는 상관없습니다.그래서 아무것도 출력되지 않는다.
    특별한 지장이 없는 사은품 문제였지만 의외로'Error caught'출력의 전제하에서 실현하기 쉬우니 주의하세요.

    최후


    그럼 어드벤트 캘린더, 디나의 기술 기사, 행사 중 등단 자료 등을 보내겠다.가능하면 팔로우 해주세요!

    좋은 웹페이지 즐겨찾기