제네릭을 사용하여 Go에서 인체공학적 오류 처리

4524 단어
이제 Go에 제네릭이 있으므로 인간 공학적인 예외와 유사한 오류 처리를 라이브러리로 구현할 수 있음을 발견했습니다. 아이디어에 대한 제 생각은 다음과 같습니다.

https://github.com/chrismwendt/go-exceptions

Go의 일반적인 오류 처리는 다음과 같습니다.

func f() error {
  err := g1()
  if err != nil {
    return err
  }

  v1, err := g2()
  if err != nil {
    return err
  }

  // ...
}


다음과 같은 오류 처리에는 몇 가지 단점이 있습니다.
  • if err != nil { return err } 3줄 추가 소요
  • 오류를 변수에 명시적으로 저장하고 오류를 반환하는 함수를 호출할 때마다 조건부로 반환해야 합니다
  • .
  • 오류 처리로 인해 코드가 복잡해지고 도메인 논리에 집중하기가 더 어려워집니다
  • .
  • f(g())가 값과 오류를 반환하고 g()가 값만 예상하는 경우 f()를 수행할 수 없습니다. 이로 인해 강제로 코드를 분할하고 임시 변수를 추가하고 if를 추가해야 합니다. 수동으로 오류 처리

  • 이것을 어떻게 더 인체 공학적으로 만들 수 있습니까? 아마도 이상적으로 Go는 Rust's ? operator에 대한 지원을 추가하겠지만 panic() recover() 을 사용하여 오류를 명시적으로 변수에 저장할 필요 없이 오류가 발생하도록 할 수 있습니다.

    이동 예외의 사용법은 다음과 같습니다.

    import ex "github.com/chrismwendt/go-exceptions"
    
    func f() (err error) {
      // Catch() calls recover() and assigns the error to &err
      defer ex.Catch(&err)
    
      // Throw() calls panic() if the error argument is not nil
      ex.Throw(g1())
    
      // Throw() also accepts a label
      ex.Throw(g2(), "g2")
    
      // Throw1() returns 1 value, Throw2() returns 2 values, etc.
      v1 := ex.Throw1(g3())
    
      // Passing arguments is easier
      v2 := ex.Throw1(g4(ex.Throw(g5())))
    
      // ...
    }
    


    이것은 몇 가지 면에서 더 인체공학적입니다.
  • 임시err 변수
  • 를 제거합니다.
  • 한 함수의 결과를 다른 함수로 더 쉽게 전달할 수 있습니다
  • .
  • 코드가 더 간결합니다
  • .
  • 라이브러리에 대해 알게 되면 IMO 코드를 더 쉽게 읽을 수 있습니다
  • .

    내부적으로:
  • Throw(err)는 기본적으로 if err != nil { panic(err) }입니다.
  • Catch(*error) 모든 패닉에서 복구하고 복구된 값을 주어진 오류
  • 에 저장합니다.

    좀 더 나아가 오류를 반환하는 대신 패닉 규칙을 채택할 수 있지만 이는 일반적인 Go 호출 규칙에서 벗어나 호출하거나 다른 코드에서 호출할 때 마찰을 일으킬 수 있습니다.

    좋은 웹페이지 즐겨찾기