언제가 아닌가

4606 단어 programminggonullnil
프로그래밍 언어에서 null 참조가 수십억 달러의 실수라는 말을 이미 들었을 것입니다.

Java의 유명하고 두려운 NullPointerException은 여러분이 알고 있거나 C의 분할 오류일 수 있습니다. 모든 상용 프로그래밍 언어는 Kool-Aid를 마시고 있습니다. 부인할 수 없습니다.

10억 달러의 실수



null 참조는 1965년에 Tony Hoare에 의해 ALGOL에 도입되었습니다. 2009년 컨퍼런스에서 그는 ALGOL에 null 참조를 도입한 것에 대해 사과하며 지난 40년 이상 동안 일련의 불행한 버그와 보안 문제로 절정에 이르렀기 때문에 "수십억 달러의 실수"라고 말했습니다.

Hoare 경은 2009년부터 QCon에서 자신의 연설에서 그것에 대해 길게 말합니다: Null References: The Billion Dollar Mistake . 시간적 여유가 있으신 분들은 가셔서 확인하시기 바랍니다. Tony Hoare는 여전히 살아있는 컴퓨터 과학의 전설 중 한 명입니다.

그리고 우리는 간다



말장난해서 죄송합니다. Go는 비교적 새로운 프로그래밍 언어이지만 여전히 null 참조로 인해 어려움을 겪고 있습니다.

Go의 한 가지 좋은 점은 모든 것이 값이라는 것입니다. 숨은 예외가 날아다니지 않고 값을 받고 확인하는 등 간단합니다.

예시:

err := db.Insert(ctx, record)
if err != nil {
    return fmt.Errorf("error while inserting record %+v: %w\n", record, err)
}


노련한 Go 개발자이거나 Go를 막 시작한 사람이라면 오류를 처리하는 이 패턴에 이미 익숙할 것입니다. 간단합니다. 그 뒤에 마법이 없습니다.

하지만 매번 nil이 Go에서 nil과 같지는 않습니다.

<nil>이 항상 <nil>은 아닙니다.



왜요?

Go에서 이 문제는 인터페이스 값에 대해 nil 검사를 수행할 때 발생합니다. Go의 인터페이스는 유형과 값을 보유합니다. nil 인터페이스 값은 해당 유형과 값이 모두 설정되지 않은 경우 nil입니다. 변수를 인터페이스에 대한 포인터로 선언하면 유형을 보유하지만 값은 여전히 ​​nil이며 여기에 nil이 nil과 같지 않은 곳이 있습니다.

예시:

func returnsError() error {
    var p *MyError = nil
    if bad() {
        p = ErrBad
    }
    return p // Will always return a non-nil error.
}


위의 예는 공식 FAQ에서 가져온 것입니다. 이 문제를 설명하는 섹션도 있습니다. Why is my nil error value not equal to nil?

위의 예에서는 오류 값을 사용하지만 이 동작은 모든 추상화에 나타나며 결국에는 유사한 문제가 발생할 수 있습니다. 이것에 대해 말하는 또 다른 좋은 출처는 David Cheney’s Practical Go advices , 섹션 “Understanding nil“ 입니다.

정말로 더 깊이 다이빙하고 싶다면 go internals bookRuss Cox’s Go Data Structures: Interfaces 이 있습니다.

디자인 문제?!



일부 gophers는 그것이 의도된 것이라고 말할 수 있으며 우리는 인터페이스에 대한 포인터를 사용하는 특이성을 이해하고 가능한 의미를 인식하여 스스로 교육해야 합니다. 나는 nil을 전혀 사용하지 않는 편이 낫겠지만, 언어가 허용할 때 nil을 피하기는 어렵습니다.

사람들은 계속 혼란스러워합니다: err != nil when err == nil with custom error type


다른 nil 종류로 Go 2에서 이 문제를 해결하기 위한 제안도 있습니다: 제안: Go 2: add kind-specific nil predeclared identifier constants

당신의 테이크는 무엇입니까?


Unsplash의 이미지 .

좋은 웹페이지 즐겨찾기