"if"문에서 변수 초기화
C ++ 17에서 if
다음과 같은 명령문 에서 변수를 초기화 할 수 있다는 것을 읽었습니다.
if (int length = 2; length == 2)
//execute something
대신에
int length = 2;
if (length == 2)
//do something
더 짧지 만 코드 가독성에 영향을 미치며 (특히이 새로운 기능을 모르는 사람들에게) 대규모 소프트웨어 개발에 나쁜 코딩 관행이라고 생각합니다.
코드를 짧게 만드는 것 외에이 기능을 사용하면 어떤 이점이 있습니까?
그것은의 범위를 제한 length
받는 사람 if
혼자. 그래서 우리가 글을 쓸 수 있었을 때 우리가 원래 얻었던 것과 같은 혜택을 얻습니다.
for(int i = 0; i < ... ; ++i) {
// ...
}
변수 누출 대신
int i;
for(i = 0; i < ... ; ++i) {
// ...
}
몇 가지 이유로 수명이 짧은 변수가 더 좋습니다. 그러나 몇 가지를 말하면 :
수명이 짧을수록 관련없는 코드 줄을 읽을 때 명심해야 할 사항이 줄어 듭니다.
i
루프 또는if
문 외부에 존재하지 않는 경우 , 그 값을 외부에 신경 쓸 필요가 없습니다. 또한 그 값이 의도 된 범위를 벗어난 프로그램의 다른 부분과 상호 작용할 것이라고 걱정할 필요가 없습니다 (i
위가 다른 루프에서 재사용되는 경우 발생할 수 있음 ). 코드를 따르고 추론하기가 더 쉽습니다.변수가 자원을 보유하고있는 경우 해당 자원은 이제 가능한 가장 짧은 기간 동안 보유됩니다. 그리고 이것은 불필요한 중괄호가 없습니다. 또한 자원이
if
혼자 와 관련이 있음이 분명합니다 . 이것을 동기 부여의 예로 고려하십시오if(std::lock_guard _(mtx); guarded_thing.is_ready()) { }
동료가 기능을 인식하지 못하는 경우 가르치십시오! 배우고 싶지 않은 프로그래머를 달래는 것은 기능을 피하는 핑계가되지 않습니다.
코드를 짧게 만드는 것 외에이 기능을 사용하면 어떤 이점이 있습니까?
변수 범위를 줄입니다. 이것은 당신이 추론해야 할 식별자의 지역성을 강화하기 때문에 의미가 있고 가독성을 증가시킵니다. 명령문 내부의 긴 init 문 if
은 피해야 한다는 데 동의 하지만, 짧은 내용은 괜찮습니다.
C ++ 17 이전의 결과에 대해 이미 초기화 및 분기를 수행 할 수 있습니다.
int *get(); // returns nullptr under some condition
if (int *ptr = get())
doStuff();
이것은 개인의 의견에 따라 다르지만 명시적인 조건을 더 읽기 쉽게 고려할 수 있습니다.
if (int *ptr = get(); ptr != nullptr)
doStuff();
게다가, 사람들이 익숙하지 않다는 사실을 언급하여 기능의 가독성에 반대하는 것은 위험합니다. 사람들은 어느 시점에서 스마트 포인터에 익숙하지 않았지만 오늘날 우리 모두는 그들이 거기에있는 것이 좋은 일이라는 데 동의합니다.
새로운 형태의 if 문은 많은 용도로 사용됩니다.
현재 이니셜 라이저는 문 앞에 선언되어 주변 범위로 유출되거나 명시 적 범위가 사용됩니다. 새로운 형식을 사용하면 이러한 코드를 더 간결하게 작성할 수 있으며 개선 된 범위 제어를 통해 오류가 발생하기 쉬운 일부 구성을 좀 더 강력하게 만들 수 있습니다.
따라서 요약하면이 문은 일반적인 코드 패턴을 단순화하고 사용자가 범위를 좁게 유지하는 데 도움이됩니다.
도움이 되었기를 바랍니다.
변수의 범위를 최소화하기 위해 생성시 유효한 경우에만 리소스를 정의하는 관용구가 있습니다 (예 : 파일 스트림 객체 ) :
if(auto file = std::ifstream("filename"))
{
// use file here
}
else
{
// complain about errors here
}
// The identifier `file` does not pollute the wider scope
때로는 실패를 기본 절로 만들고 유효한 리소스를 절로 만들기 위해 해당 테스트의 논리를 반대로 할 수 있기를 원합니다 else
. 이전에는 불가능했습니다. 하지만 이제 우리는 할 수 있습니다 :
if(auto file = std::ifstream("filename"); !file)
{
// complain about errors here
}
else
{
// use file here
}
예를 들어 예외가 발생할 수 있습니다.
if(auto file = std::ifstream(filename); !file)
throw std::runtime_error(std::strerror(errno));
else
{
// use file here
}
어떤 사람들 은 오류 발생시 함수가 조기 에 중단 되고 그렇지 않으면 진행 되도록 코딩하는 것을 좋아합니다 . 이 관용구는 어떤 사람들이 더 자연스럽게 생각할 수있는 연속 논리 위에 물리적으로 중단 논리를 둡니다.
논리적 이벤트에 특히 유용합니다. 이 예를 고려하십시오.
char op = '-';
if (op != '-' && op != '+' && op != '*' && op != '/') {
std::cerr << "bad stuff\n";
}
Seems a bit rough. Unless you are very familiar with OR, AND
with negations, you might need to pause and think about this logic - which is generally poor design. With the if-initialization
you can add expressiveness.
char op = '-';
if (bool op_valid = (op == '-') || (op == '+') || (op == '*') || (op == '/'); !op_valid) {
std::cerr << "bad stuff\n";
}
the named variable can be re-used inside the if
too. E.g:
if (double distance = std::sqrt(a * a + b * b); distance < 0.5){
std::cerr << distance << " is too small\n";
}
This is great, especially given that the variable is scoped and therefore doesn't pollute the space afterwards.
This is an extension of an existing feature, which aids readability in my experience.
if (auto* ptr = get_something()) {
}
Here we both create the variable ptr
and we test against it being non-null. The scope of ptr
is limited to where it is valid. It is far, far easier to convince yourself that all use of ptr
is valid.
But what if we are talking about something that doesn't convert to bool
that way?
if (auto itr = find(bob)) {
}
작동하지 않습니다. 그러나이 새로운 기능을 통해 다음을 수행 할 수 있습니다.
if (auto itr = find(bob); itr != end()) {
}
"이 초기화가 유효 할 때"라는 절을 추가하십시오.
본질적으로 이것은 "일부 표현식을 초기화하고 유효 할 때 일부 코드를 수행합니다. 유효하지 않으면 폐기"를 의미하는 토큰 세트를 제공합니다.
C ++ 98 이후로 포인터 테스트 트릭을 수행하는 것은 관용적이었습니다. 일단 그것을 받아 들인다면,이 확장은 당연합니다.
참고 URL : https://stackoverflow.com/questions/56866458/initializing-variables-in-an-if-statement
'Programing' 카테고리의 다른 글
느린 뷰 렌더링의 원인 진단 (0) | 2020.10.12 |
---|---|
build.gradle의 local.properties에 정의 된 속성을 읽는 방법 (0) | 2020.10.12 |
System.Speech.Recognition과 Microsoft.Speech.Recognition의 차이점은 무엇입니까? (0) | 2020.10.12 |
Tomcat의 기본 사용자 이름과 비밀번호는 무엇입니까? (0) | 2020.10.12 |
젠킨스에서 빌드 번호를 재설정하는 방법은 무엇입니까? (0) | 2020.10.11 |