Qual é o benefício de vários valores de retorno

4

Eu sinto como se uma declaração de retorno devesse retornar apenas um valor. Quando ele retorna vários, as coisas ficam confusas. Eu sei desde o tipo de retorno em Java tem que ser declarado, isso é difícil de fazer, mas em linguagens como o Python é um piscar de olhos.

Vários valores de retorno são um sinal de design ou estilo de codificação incorreto?

Exemplo de Python


def get_name():
   # you code
   return first_name, last_name

    
por AngryBird 26.07.2011 / 20:55
fonte

7 respostas

13

Não é um sinal de nada e não é nem bom nem mau design ou estilo de codificação.

Retornar vários valores pode, na verdade, ser apropriado e permitir escrever menos código. Vamos pegar um exemplo de um método que pega uma string como "-123abc" e a converte em um inteiro como -123 :

(bool, int) ParseInteger(string text)
{
    // Code goes here.
}

retorna ambos:

  • um valor indicando se a operação foi um sucesso,
  • o número convertido da string.

Como podemos refatorar isso?

1. Exceções

Podemos adicionar exceções, se o idioma oferecer suporte a elas. Lembre-se que na maioria das linguagens, as exceções são caras em recursos. Isso significa que, se você tiver que lidar com muitos números diferentes, é melhor evitar lançar uma exceção toda vez que a string não puder ser convertida em um número.

2. Nova aula

Podemos criar uma classe e retornar uma instância de um objeto dessa classe.

Por exemplo:

class ParsedInteger
{
    bool IsSuccess { get; set; }
    int Number { get; set; }
}

É mais fácil de entender? Mais curto para escrever? Isso traz alguma coisa? Eu não penso assim.

3. Parâmetros de saída

Se o idioma for compatível, também podemos usar os parâmetros out . Essa é a abordagem do C # em que retornar vários valores não é possível. Por exemplo, ao analisar um número, usamos: bool isSuccess = int.TryParse("-123abc", out i) . Não sei como é melhor usar os parâmetros out em comparação com vários valores. A sintaxe não é óbvia, e mesmo o próprio StyleCop (a ferramenta usada para impor as regras de estilo padrão da Microsoft no código) reclama sobre esses parâmetros, sugerindo removê-los quando possível.

Finalmente, em linguagens como C #, onde não há como retornar vários valores, as coisas são adicionadas progressivamente para imitar o comportamento. Por exemplo, Tuple foi adicionado para permitir o retorno de vários valores sem precisar escrever sua própria classe ou usar os parâmetros out .

    
por 26.07.2011 / 21:14
fonte
6

Quando sua função retorna uma referência a um objeto que contém vários membros, ela está retornando um ou vários valores? No exemplo que você mostra, a função está retornando um objeto do tipo tuple. O Python apenas suporta o 'açúcar' sintático para que você não precise excluir explicitamente os membros ao fazer designações a partir do valor de retorno da função.

    
por 26.07.2011 / 21:19
fonte
4

Bem, eu vi isso recentemente:

current_pixel = pixel[x,y]
# Formula for Orange: 50% red and more green than blue
if float(current_pixel[0])/(current_pixel[0]+current_pixel[1]+current_pixel[2]+1)>0.5 and current_pixel[1]>current_pixel[2]:

E aqui está a maneira sensata de fazer isso:

red, green, blue = pixel[x,y]
if green > blue and float(red) / (red + green + blue + 1) > 0.5:
    
por 26.07.2011 / 21:36
fonte
3

Talvez seja melhor você encapsular esses valores em um objeto - já que quem sabe quando você decidirá retornar ainda mais dados, certo? :)

    
por 26.07.2011 / 21:13
fonte
3

Bem, espero que não seja um sinal de design ruim ou estilo de codificação, como é comum nas bibliotecas internas. Seu exemplo de first_name, last_name parece perfeitamente razoável para mim. Uma vez que você vá além de alguns valores razoáveis e relacionados, provavelmente fará sentido procurar outras alternativas para evitar o retorno de uma lista enorme de valores posicionais.

    
por 26.07.2011 / 21:14
fonte
2

Suponho que você esteja falando sobre retornar algo como uma tupla, objeto ou outras estruturas de dados compostos. Usá-los muitas vezes pode tornar um programa mais claro, mas é preciso ter cuidado com a coesão e o acoplamento. Já vi casos em que uma enorme estrutura de dados está sendo passada, o que poderia ser facilmente substituído por globais, quando partes diferentes do código deveriam ter sido responsáveis por partes pequenas e consistentes dele.

    
por 26.07.2011 / 21:14
fonte
1

Não, eu não acho que você possa declarar que isso é um estilo ruim só porque você acha que é "confuso". Na verdade, por que deveria ser mais confuso do que ter vários parâmetros ao chamar a função? É mais com o que você está acostumado e se você o usa com frequência suficiente, você não terá mais dificuldades.

    
por 26.07.2011 / 21:17
fonte