C 스타일 언어를 사용하지 않고 &&
질문에서와 동일한 코드를 수행해야 한다고 가정 해 봅시다 .
코드는 다음과 같습니다.
if(smartphone != null)
{
if(smartphone.GetSignal() > 50)
{
// Do stuff
}
}
이 패턴은 많이 나타납니다.
이제 가상의 언어 버전 2.0이 소개한다고 상상해보십시오 &&
. 당신이 생각했던 얼마나 멋진 생각!
&&
위의 예제를 수행하는 인식 된 관용적 수단입니다. 그것을 사용하는 것은 나쁜 습관이 아닙니다. 실제로 위와 같은 경우에는 그것을 사용하지 않는 것이 좋지 않습니다. 그런 언어의 경험이 풍부한 코더 else
는 정상적인 방식으로 일을하지 않는 이유가 무엇인지 궁금 할 것입니다.
이 언어는 첫 번째 문장이 거짓이면 두 번째 문장을 평가해도 아무런 의미가 없으므로 null 참조 예외가 발생하지 않는다는 것을 알고 있기 때문에 언어는 영리합니다.
아니, 당신은 첫 번째 문이 거짓이라면 심지어 두 번째 문을 평가 아무 소용이 없다는 것을 알고 있기 때문에, 영리하다. 언어는 바위 상자처럼 바보이며 당신이 말한대로했습니다. (John McCarthy는 훨씬 더 영리했고 단락 평가는 언어가 갖는 유용한 것임을 깨달았습니다).
좋은 습관과 나쁜 습관은 종종 필요한만큼 영리하지만 더 이상 영리하지 않기 때문에 당신이 영리하고 언어가 영리하다는 것의 차이가 중요합니다.
치다:
if(smartphone != null && smartphone.GetSignal() > ((range = (range != null ? range : GetRange()) != null && range.Valid ? range.MinSignal : 50)
이것은 코드를 확장하여를 확인합니다 range
. range
가 null 인 경우는 호출에 의해 설정하려고 GetRange()
하지만 실패 할 range
가능성이 있으므로 여전히 null 일 수 있습니다. 이후에 range가 null이 아닌 경우 Valid
해당 MinSignal
속성이 사용되며, 그렇지 않으면 기본값 50
이 사용됩니다.
이것은 &&
너무 달려 있지만 한 줄에 넣는 것이 너무 영리합니다 (100 % 확실하지 않으며 그 사실이 내 요점을 입증하기 때문에 다시 확인하지 않을 것입니다).
그것은 &&
여기서 문제가 아니지만, 그것을 사용하여 하나의 표현 (많은 것)에 많은 것을 넣을 수있는 능력은 이해하기 어려운 표현을 불필요하게 쓰는 능력 (악한 것)을 증가시킵니다.
또한:
if(smartphone != null && (smartphone.GetSignal() == 2 || smartphone.GetSignal() == 5 || smartphone.GetSignal() == 8 || smartPhone.GetSignal() == 34))
{
// do something
}
여기 &&
에서는 특정 값에 대한 검사와 사용을 결합 합니다. 이것은 전화 신호의 경우 현실적이지 않지만 다른 경우에는 나타납니다. 여기, 내가 영리하지 못한 예입니다. 다음을 수행 한 경우 :
if(smartphone != null)
{
switch (smartphone.GetSignal())
{
case 2: case 5: case 8: case 34:
// Do something
break;
}
}
가독성과 성능이 모두 향상되었을 것입니다 (여러 번의 호출 GetSignal()
은 최적화되지 않았을 것임).
여기서 다시 한 번 문제는 &&
특정 망치를 들고 손톱으로 다른 모든 것을 보는 것만 큼 중요하지 않습니다 . 사용하지 않는 것보다 더 나은 것을 할 수 있습니다
모범 사례에서 벗어나는 마지막 사례는 다음과 같습니다.
if(a && b)
{
//do something
}
다음과 비교 :
if(a & b)
{
//do something
}
우리가 후자를 선호하는 이유에 대한 고전적인 주장은 b
우리 a
가 진실 인지 아닌지 를 평가 하는 데 부작용이 있다는 것입니다 . 나는 그 부작용이 너무 중요하다면 별도의 코드 줄에서 발생하게하십시오.
그러나 효율성면에서 두 가지 중 하나가 더 좋을 것입니다. 첫 번째 코드는 분명히 적은 코드를 실행하여 ( b
한 코드 경로에서 전혀 평가하지 않음) 평가 하는 데 걸리는 시간을 절약 할 수 있습니다 b
.
첫 번째는 또한 하나 더 지점이 있습니다. 다음과 같이 가상 C 스타일 언어로 다시 작성하는지 고려하십시오 &&
.
if(a)
{
if(b)
{
// Do something
}
}
그 여분 if
은 우리의 사용에 숨겨져 &&
있지만 여전히 있습니다. 따라서 분기 예측이 발생하고 따라서 잠재적으로 분기 잘못 예측되는 경우가 있습니다.
이런 이유로 if(a & b)
코드가 더 효율적일 수 있습니다.
여기서는 if(a && b)
여전히 가장 모범 사례 접근 방식 이라고 말하고 싶습니다 .보다 일반적으로, 경우에 따라 유일하게 실행 가능한 유일한 방법 ( 거짓 b
이면 오류가 발생합니다 a
)과 그렇지 않은 경우 가 더 빠릅니다. if(a & b)
특정 경우에 종종 유용한 최적화 라는 점 은 주목할 가치가 있습니다.