함수에 종료 지점이 하나만 있어야하는 이유는 무엇입니까? [닫은]
가독성과 효율성을 잃기 때문에 단일 종료점 함수가 코딩에 나쁜 방법이라고 항상 들었습니다. 나는 아무도 반대편을 주장하는 것을 들어 본 적이 없습니다.
나는 이것이 CS와 관련이 있다고 생각했지만이 질문은 cstheory stackexchange에서 떨어졌습니다.
생각에는 여러 학파가 있으며 주로 개인적 선호도에 달려 있습니다.
하나는 출구 지점이 하나뿐이면 덜 혼란 스럽습니다. 메소드를 통해 단일 경로가 있고 출구를 찾을 위치를 알고 있습니다. 마이너스 쪽에서 들여 쓰기를 사용하여 중첩을 나타내는 경우 코드가 오른쪽으로 크게 들여 쓰기되어 모든 중첩 범위를 따르는 것이 매우 어려워집니다.
또 다른 방법은 전제 조건을 확인하고 메서드 시작시 일찍 종료 할 수 있으므로 메서드 본문 전체가 오른쪽으로 5 마일 떨어져 들여 쓰기되지 않고 특정 조건이 참임을 메서드 본문에서 알 수 있다는 것입니다. 이는 일반적으로 걱정해야하는 범위의 수를 최소화하므로 코드를 훨씬 쉽게 따라갈 수 있습니다.
세 번째는 원하는 곳 어디에서나 나갈 수 있다는 것입니다. 예전에는 더 혼란 스러웠지만 이제는 도달 할 수없는 코드를 감지하는 구문 색상 편집기와 컴파일러가 있으므로 처리하기가 훨씬 쉽습니다.
나는 중간 캠프에 있습니다. 단일 종료 지점을 적용하는 것은 무의미하거나 심지어 비생산적인 제한 IMHO이지만, 메소드 전체를 무작위로 종료하면 때때로 논리를 따르기 어렵게되어 주어진 코드가 있는지 확인하기가 어려워집니다. 실행. 그러나 방법을 "게이팅"하면 방법 본문을 크게 단순화 할 수 있습니다.
일반적인 권장 사항은 return 문이 가능한 경우 부작용이있는 첫 번째 코드 앞이나 부작용이있는 마지막 코드 뒤에 위치해야한다는 것입니다. 나는 다음과 같은 것을 고려할 것입니다.
if (! argument) // null이 아닌지 확인
반환 ERR_NULL_ARGUMENT;
... 널이 아닌 인수 처리
만약 (OK)
반환 0;
그밖에
반환 ERR_NOT_OK;
보다 명확 :
int return_value;
if (argument) // 널이 아님
{
.. 널이 아닌 인수 처리
.. 결과를 적절하게 설정
}
그밖에
결과 = ERR_NULL_ARGUMENT;
반환 결과;
특정 조건으로 인해 함수가 어떤 작업도 수행하지 못하도록해야하는 경우 함수가 어떤 작업을 수행 할 수있는 지점보다 높은 지점에서 함수에서 일찍 복귀하는 것을 선호합니다. 함수가 부작용이있는 작업을 수행 한 후에는 모든 부작용을 처리해야 함을 명확히하기 위해 바닥에서 돌아 오는 것을 선호합니다.
단일 진입 점과 출구 점은 구조화 된 프로그래밍과 단계별 스파게티 코딩의 원래 개념이었습니다. 변수에 할당 된 메모리 공간을 적절하게 정리해야하므로 여러 종료점 함수에 더 많은 코드가 필요하다는 믿음이 있습니다. 함수가 변수 (리소스)를 할당하고 적절한 정리없이 조기에 함수에서 나가면 리소스 누수가 발생하는 시나리오를 고려하십시오. 또한 모든 종료 전에 정리를 구성하면 많은 중복 코드가 생성됩니다.
대부분의 경우 결과물의 요구에 따라 결정됩니다. "예전에는"여러 리턴 포인트가있는 스파게티 코드가 메모리 누수를 유발했습니다. 그 방법을 선호하는 코더는 일반적으로 잘 정리되지 않았기 때문입니다. 또한 일부 컴파일러가 중첩 된 범위에서 반환하는 경우 반환 중에 스택이 팝될 때 반환 변수에 대한 참조를 "손실"하는 문제가있었습니다. 보다 일반적인 문제는 함수의 호출 상태가 반환 상태와 정확히 동일하도록 시도하는 재진입 코드입니다. oop의 돌연변이가 이것을 위반했고 개념은 보류되었습니다.
여러 출구 지점이 제공하는 속도가 필요한 결과물, 특히 커널이 있습니다. 이러한 환경에는 일반적으로 자체 메모리 및 프로세스 관리 기능이 있으므로 누수 위험이 최소화됩니다.
개인적으로 단일 종료 지점을 갖는 것을 좋아합니다. 종종이를 사용하여 return 문에 중단 점을 삽입하고 코드가 해당 솔루션을 결정하는 방법에 대한 코드 검사를 수행하기 때문입니다. 나는 단지 입구로 가서 단계를 통과 할 수 있으며, 광범위하게 중첩되고 재귀적인 솔루션을 사용합니다. 코드 검토 자로서 함수의 다중 반환에는 훨씬 더 깊은 분석이 필요합니다. 따라서 구현 속도를 높이기 위해 수행하는 경우 Peter를 강탈하여 Paul을 구하는 것입니다. 코드 검토에 더 많은 시간이 필요하므로 효율적인 구현에 대한 가정이 무효화됩니다.
-2 센트
자세한 내용은이 문서를 참조하십시오 : NISTIR 5459
제 생각에는 한 지점에서만 함수 (또는 다른 제어 구조)를 종료하라는 조언이 종종 과매도되었습니다. 일반적으로 한 지점에서만 나가는 이유는 두 가지입니다.
- Single-exit code is supposedly easier to read and debug. (I admit that I don't think much of this reason, but it is given. What is substantially easier to read and debug is single-entry code.)
- Single-exit code links and returns more cleanly.
The second reason is subtle and has some merit, especially if the function returns a large data structure. However, I wouldn't worry about it too much, except ...
If a student, you want to earn top marks in your class. Do what the instructor prefers. He probably has a good reason from his perspective; so, at the very least, you'll learn his perspective. This has value in itself.
Good luck.
I used to be an advocate of single-exit style. My reasoning came mostly from pain...
Single-exit is easier to debug.
Given the techniques and tools we have today, this is a far less reasonable position to take as unit tests and logging can make single-exit unnecessary. That said, when you need to watch code execute in a debugger, it was much harder to understand and work with code containing multiple exit points.
This became especially true when you needed to interject assignments in order to examine state (replaced with watch expressions in modern debuggers). It was also too easy to alter the control flow in ways that hid the problem or broke the execution altogether.
Single-exit methods were easier to step through in the debugger, and easier to tease apart without breaking the logic.
The answer is very context dependent. If you are making a GUI and have a function which initialises API's and opens windows at the start of your main it will be full of calls which may throw errors, each of which would cause the instance of the program to close. If you used nested IF statements and indent your code could quickly become very skewed to the right. Returning on an error at each stage might be better and actually more readable while being just as easy to debug with a few flags in the code.
If, however, you are testing different conditions and returning different values depending on the results in your method it may be much better practice to have a single exit point. I used to work on image processing scripts in MATLAB which could get very large. Multiple exit points could make the code extremely hard to follow. Switch statements were much more appropriate.
The best thing to do would be to learn as you go. If you are writing code for something try finding other people's code and seeing how they implement it. Decide which bits you like and which bits you don't.
If you feel like you need multiple exit points in a function, the function is too large and is doing too much.
I would recommend reading the chapter about functions in Robert C. Martin's book, Clean Code.
Essentially, you should try to write functions with 4 lines of code or less.
Some notes from Mike Long’s Blog:
- The first rule of functions: they should be small
- The second rule of functions: they should be smaller than that
- Blocks within if statements, while statements, for loops, etc should be one line long
- …and that line of code will usually be a function call
- There should be no more than one or maybe two levels of indentation
- Functions should do one thing
- Function statements should all be at the same level of abstraction
- A function should have no more than 3 arguments
- Output arguments are a code smell
- Passing a boolean flag into a function is truly awful. You are by definition doing two --things in the function.
- Side effects are lies.
참고URL : https://stackoverflow.com/questions/4838828/why-should-a-function-have-only-one-exit-point
'Programing' 카테고리의 다른 글
| Microsoft.DotNet.Props를 찾을 수 없습니다. (0) | 2020.09.12 |
|---|---|
| Visual Studio 2017 및 C # 7.0을 사용하는 메서드에서 Tuple을 반환 할 수 없습니다. (0) | 2020.09.12 |
| Objective-C의 범주를 사용하여 메서드 재정의 (0) | 2020.09.12 |
| 오늘부터 navigator.platform의 가능한 값 목록은 무엇입니까? (0) | 2020.09.12 |
| ASP.Net Core Web API의 반환 파일 (0) | 2020.09.12 |