Golang 블로거가 지나간 error에 대한 구덩이들

2660 단어
더 많은 멋진 문장https://deepzz.comDesc: 왜 nil의 error가 nil과 같지 않습니까
이 글은 내가 Golang 개발 학습 과정에서 만났던 error와 관련된 구덩이를 기록하는 데 쓰인다.어쩌면 너도 만났을지도 몰라, 어쩌면 너는 여기서 답을 찾을 수 있을지도 몰라.물론 error의 예를 통해 너도 다른 장면을 연상해야 한다.

err != nil


첫 번째 문제는 왜 nil의 error가 nil과 같지 않습니까?
다음 코드를 생각해 보십시오.
package main

import (
    "errors"
    "fmt"
)

type Err struct {
    err string
}

func (e *Err) Error() string {
    return e.err
}

func returnErr() *Err {
    return nil
}

func main() {
    var err error

    err = returnErr()
    fmt.Println(err, err != nil)
}

먼저 returnErr() 값이 nil인 *Err를 되돌려주고 err에 값을 부여합니다. 그러면 fmt는 어떤 결과를 출력합니까?예:
 false

오류, 인쇄됩니다 true.당시에 자신도 두서가 없었고 학예가 정교하지 않아서 신에게 물어본 후에 이것이 인터페이스 인터페이스로 인해 일어난 것임을 알게 되었다.구체적으로 홈페이지 FAQ를 볼 수 있다.
간단하게 말하자면, 인터페이스는 두 요소value와 type에 의해 표시됩니다.value와 type이 동시에 nil일 때만 판단interface == nil은true이다.err = returnErr() 이 과정에서value는nil이지만 type은*Err이다.
어떻게 이 문제를 해결합니까?내가 보기에는 근원적으로만 착수할 수 있을 것 같다. 두 가지 방식:
  • 이 결과를 인터페이스 변수에 부여하지 마십시오.예를 들어 err = returnErr()err1 := returnErr() 로 바꾸면 방해를 피할 수 있다.
  • 함수를 사용자 정의 유형(예: *Err)으로 되돌리지 마십시오.오류 패키지를 error로 필터링해야 합니다(예:
  • .
    func Err() (err error) {
        if e := returnErr(); e != nil {
            return e
        }
    
        return
    }
    

    err == nil


    왜 또 err == nil 질문이 있습니까?이 문제는 내가 표준 라이브러리 원본 코드를 보았을 때 발견한 것이다. 그중에는 다음과 같은 단락이 있다.
    func (e *AddrError) Error() string {
        if e == nil { //  ,  nil
            return ""
        }
        s := e.Err
        if e.Addr != "" {
            s = "address " + e.Addr + ": " + s
        }
        return s
    }
    

    왜 다시 판단했을까e == nil 난해했다.모두가 알다시피 방법과 변수는 서로 다른 구역에 저장되어 있다. 우리가 빈 바늘 형식의 변수 (예를 들어var e *Addr Error) 를 사용하여 방법을 호출할 때, 이 방법은 실행되며, 이 빈 바늘 변수의 지침 해제 작업을 실행할 때만 panic를 실행할 수 있다.
    다음은 예입니다.
    // Package main provides ...
    package main
    
    import "fmt"
    
    func main() {
        var e *Err
        e.Print()
        e.Printf()
        e.Println()
    }
    
    type Err struct {
        err string
    }
    
    func (e *Err) Print() {
        fmt.Println("e.Print run")
    }
    
    func (e *Err) Printf() {
        fmt.Println(e.err)
    }
    
    func (e Err) Println() {
        fmt.Println("e.Println run")
    }
    

    1、e.Print()는 완전히 실행할 수 있으며 포인터를 풀지 않았습니다.
    2. e.Printf() e.err를 호출할 때 지침 조작을 이해하기 때문에panic를 사용한다.
    3, e.Println() 수용자는 Err가 아니라 Err이기 때문에 Golang 내부에서 이 함수를 호출할 때 자동으로 바늘을 풀기 때문에 panic을 사용한다.

    좋은 웹페이지 즐겨찾기