É um princípio de estilo de codificação - por exemplo, o princípio de saída única
As pessoas que ainda se preocupam com uma saída única ou múltipla ainda estão presas no final dos anos 60. Naquela época, essa discussão era importante, pois estávamos na infância de programadores estruturados, e havia um campo bastante numeroso proclamando que as descobertas por trás do Teorema do Programa Estruturado da Bohm-Jacopini não eram universalmente aplicáveis a todas as construções de programação.
É algo que deveria ter sido resolvido há muito tempo. Bem, foi acertado (quase 4 décadas para ser preciso, tanto na Academia quanto na indústria), mas as pessoas (aquelas que são absolutamente a favor ou contra) não estão prestando atenção.
Quanto ao restante das minhas respostas, é tudo relativo (o que não está no software?):
Sim. Na maioria das vezes, para o caso geral, com advertências específicas para casos extremos e construções de programação específicas da linguagem.
Sempre ou apenas algumas vezes?
A maior parte do tempo.
Quanta diferença isso realmente faz?
Depende.
Código legível vs código ilegível. Maior complexidade (que agora deveríamos saber aumenta a probabilidade de introdução de erros) versus complexidade mais simples (e, portanto, menor probabilidade de erros). Linguagens cujos compiladores não adicionam um retorno implícito (por exemplo, Pascal, Java ou C #) e aqueles que padrão para int (C e C ++).
No final, é uma habilidade aprimorada com homem / hora atrás de um teclado. Às vezes, não há problema em ter várias instruções de retorno, como aqui (em algum pseudocódigo de Pascal'esque):
function foo() : someType
begin
if( test1 == true )
then
return x;
end
doSomethignElseThatShouldnHappenIfTest1IsTrue();
return somethingElse();
end;
A intenção é clara e o algoritmo é pequeno o suficiente e descomplicado o suficiente para não garantir a criação de uma variável 'flag' que contém o valor de retorno eventual usado em um único ponto de retorno. O algoritmo pode estar com erro, mas sua estrutura é simples o suficiente para que o esforço em detectar um erro seja (muito provavelmente) insignificante.
Às vezes não é (aqui usando um pseudocódigo do tipo C):
switch(someVal)
{
case v1 : return x1;
case v2 : return x2:
case v3 : doSomething(); // fall-through
case v4: // fall-through
case v5: // fall-through
case v6: return someXthingie;
...
...
default:
doSomething(); // no return statement yet
}
Aqui, o algoritmo não possui uma estrutura simples, e a instrução switch (do tipo C) permite etapas de transição que podem ou não ser feitas intencionalmente como parte do algoritmo.
Talvez o algoritmo esteja correto, mas mal escrito.
Ou talvez, por forças externas além da capacidade do programador, essa seja a representação real (e correta) de um algoritmo legitimamente necessário.
Talvez esteja errado.
Descobrir a verdade de tudo isso requer muito mais esforço do que no exemplo anterior. E aqui está algo em que eu acredito fortemente (lembre-se de que não tenho estudos formais para apoiar isso):
Supondo que um trecho de código que seja considerado correto:
Várias instruções de retorno aumentam a legibilidade e a simplicidade de um trecho de código, se o trecho representar um algoritmo simples com uma estrutura de fluxo inerentemente simples. Por simples, não quero dizer pequeno, mas quero dizer intrinsecamente compreensível ou auto-evidência , o que não requer esforço de leitura desproporcional (nem induz as pessoas a vomitar, amaldiçoar a mãe de alguém ou engolir uma bala quando precisam lê-la. )
Uma única declaração de retorno aumenta a legibilidade e a simplicidade de um pedaço de código se o valor de retorno for calculado durante a execução do algoritmo ou se as etapas no algoritmo responsável por calculá-lo puderem ser agrupadas em um local dentro da estrutura do algoritmo. .
Uma única declaração de retorno diminui a legibilidade e a simplicidade de um pedaço de código se exigir atribuições a uma ou mais variáveis de flag, com os locais de tais atribuições não sendo uniformemente localizados em todo o algoritmo.
Várias instruções de retorno diminuem a legibilidade e a simplicidade de um pedaço de código, se as instruções de retorno não são distribuídas uniformemente pelo algoritmo e se demarcam blocos de código mutuamente exclusivos que não são uniformes em tamanho ou estrutura entre si.
Isso está intimamente relacionado à complexidade de um trecho de código em questão. E isso, por sua vez, está relacionado a medidas de complexidade ciclomática e de halstead. A partir disso, pode-se observar o seguinte:
Quanto maior o tamanho de uma sub-rotina ou função, maior e mais complexa é a estrutura do fluxo de controle interno e maior a probabilidade de você enfrentar uma questão de usar declarações de retorno múltiplas ou únicas.
A conclusão disso é: mantenha suas funções pequenas fazendo uma coisa e apenas uma coisa (e fazendo bem). Se exibirem métricas de complexidade ciclomática e de halstead nominalmente pequenas, elas não apenas serão provavelmente corretas e implementarão tarefas que são compreensíveis, como também suas estruturas internas serão relativamente evidentes.
Então, e só então você pode facilmente e sem perder muito sono, pode decidir se deve usar um único retorno e vários retornos sem correr muitos riscos de introduzir erros com qualquer uma das opções.
Pode-se também analisar tudo isso e sugerir que, quando as pessoas lutam com a questão de retornos únicos ou múltiplos retornos, é porque - por inexperiência, estupidez ou falta de ética no trabalho - eles não escrevem código limpo e tendem a escrever funções monstruosas com total desconsideração das medidas ciclomáticas e halstead.