null을 올바르게 사용
사용 방법에는 여러 가지가 null
있습니다. 가장 일반적이고 의미 적으로 올바른 방법은 단일 값 이 있거나 없을 때 사용하는 것 입니다. 이 경우 값 null
은 데이터베이스의 레코드와 같은 의미이거나 의미가 있습니다.
이러한 상황에서는 대부분 의사 코드로 다음과 같이 사용합니다.
if (value is null) {
doSomethingAboutIt();
return;
}
doSomethingUseful(value);
문제
그리고 그것은 매우 큰 문제가 있습니다. 문제는 호출 할 doSomethingUseful
때까지 값이 확인되지 않았을 수 있다는 것입니다 null
! 그렇지 않은 경우 프로그램이 중단 될 수 있습니다. 그리고 사용자에게는 "끔찍한 오류 : 원하는 값이지만 null이 있습니다!"와 같은 오류 메시지가 표시되지 않을 수도 있습니다. (업데이트 후 :와 같은 정보 오류가 적 Segmentation fault. Core dumped.
거나 더 나쁘지만 오류가 발생하지 않고 경우에 따라 null을 잘못 조작하는 경우도 있음)
점검 null
및 null
상황 처리 를 잊어 버리는 것은 매우 일반적인 버그 입니다. 발명 토니 호어는 이유는 null
그가 1965 년 억 달러 실수를 한 것으로 2009 년에 QCon 런던라는 소프트웨어 회견에서 말했다 :
https://www.infoq.com/presentations/Null-References-The-Billion-Dollar- 실수-토니-호 아르
문제 피하기
일부 기술과 언어 null
는 다른 방법으로 잊을 수없는 검사를 하여 버그의 양을 줄입니다.
예를 들어 Haskell에는 Maybe
null 대신 모나드 가 있습니다. DatabaseRecord
이것이 사용자 정의 유형 이라고 가정하십시오 . Haskell에서 type 값은 Maybe DatabaseRecord
같 Just <somevalue>
거나 같을 수 있습니다 Nothing
. 그런 다음 다른 방법으로 사용할 수 있지만 사용 방법에 Nothing
관계없이 알지 못하면 일부 작업을 적용 할 수 없습니다 .
예를 들어이 함수가 호출 zeroAsDefault
반환 x
에 대한 Just x
과 0
를 들어 Nothing
:
zeroAsDefault :: Maybe Int -> Int
zeroAsDefault mx = case mx of
Nothing -> 0
Just x -> x
Christian Hackl은 C ++ 17과 Scala는 각자의 방법이 있다고 말합니다. 따라서 언어에 그런 것이 있는지 찾아서 사용하려고 할 수 있습니다.
널은 여전히 널리 사용됩니다
더 나은 것이 없다면 사용하는 것이 좋습니다 null
. 계속 조심하십시오. 함수의 타입 선언은 어쨌든 도움이 될 것입니다.
또한 그다지 진보적이지는 않지만 동료가 사용하고 싶은지 null
또는 다른 것을 확인해야합니다 . 이들은 보수적 일 수 있으며 몇 가지 이유로 새로운 데이터 구조를 사용하지 않을 수 있습니다. 예를 들어 언어의 이전 버전을 지원합니다. 이러한 것들은 프로젝트의 코딩 표준에 선언되어 팀과 적절히 논의되어야합니다.
당신의 제안에
별도의 부울 필드를 사용하는 것이 좋습니다. 그러나 어쨌든 확인해야하지만 여전히 확인을 잊어 버릴 수 있습니다. 그래서 여기서이긴 것은 없습니다. 매번 두 값을 업데이트하는 것과 같은 다른 것을 잊어 버릴 수 있다면 더 나쁩니다. 확인을 잊어 버리는 문제가 null
해결되지 않으면 아무런 의미가 없습니다. 피하는 null
것은 어려우므로 악화시키는 방식으로하지 않아야합니다.
null을 사용하지 않는 방법
마지막으로 null
잘못 사용하는 일반적인 방법이 있습니다 . 이러한 방법 중 하나는 배열 및 문자열과 같은 빈 데이터 구조 대신 사용하는 것입니다. 빈 배열은 다른 배열과 마찬가지로 올바른 배열입니다! 여러 값에 맞을 수 있고 비어있을 수있는, 즉 길이가 0 인 데이터 구조에는 거의 항상 중요하고 유용합니다.
대수 관점에서 문자열의 빈 문자열은 숫자의 경우 0과 매우 비슷합니다.
a+0=a
concat(str, '')=str
: 빈 문자열은 일반적으로 문자열은 모노 이드 될 수 있습니다
https://en.wikipedia.org/wiki/Monoid
당신이 당신을 위해 그 중요하지하지 않는 경우.
이제이 예제를 사용하여 프로그래밍하는 것이 왜 중요한지 살펴 보겠습니다.
for (element in array) {
doSomething(element);
}
빈 배열을 여기에 전달하면 코드가 정상적으로 작동합니다. 아무것도하지 않을 것입니다. 그러나 null
여기에 전달하면 "null을 반복 할 수 없습니다. 죄송합니다"와 같은 오류로 충돌이 발생합니다. 우리는 그것을 감쌀 수는 if
있지만 덜 깨끗하고 다시 확인해야합니다.
null 처리 방법
어떤 doSomethingAboutIt()
일을하고, 특히이 예외를 throw할지 여부를해야 또 다른 복잡한 문제입니다. 간단히 말해 null
주어진 작업에 허용되는 입력 값 인지 여부 와 응답시 예상되는 값에 따라 다릅니다 . 예상하지 못한 이벤트는 예외입니다. 그 주제에 대해서는 더 이상 다루지 않겠습니다. 이 답변은 이미 오래되었습니다.
std::optional
또는을 사용Option
합니다. 다른 언어로, 당신은 적절한 메커니즘을 직접 구축해야 할 수도 있고,null
더 관용적이기 때문에 실제로 또는 유사한 것에 의지 할 수도 있습니다 .