Usos apropriados de instruções de troca de fall-through

14

Quando é apropriado usar uma instrução de troca (clássica)? Esse uso é recomendado e incentivado ou deve ser evitado a todo custo?

    
por shabunc 25.10.2011 / 21:12
fonte

7 respostas

15

Veja um exemplo onde seria útil.

public Collection<LogItems> GetAllLogItems(Level level) {
    Collection<LogItems> result = new Collection<LogItems>();
    switch (level) {
        // Note: fall through here is INTENTIONAL
        case All:
        case Info:
             result.Add(GetItemsForLevel(Info));
        case Warning:
             result.Add(GetItemsForLevel(Warning));
        case Error:
             result.Add(GetItemsForLevel(Error));
        case Critical:
             result.Add(GetItemsForLevel(Critical));
        case None:
    }
    return result;
}

Esse tipo de coisa (em que um caso inclui o outro) é bastante raro, penso, e é por isso que algumas linguagens mais novas não permitem o fallover ou exigem uma sintaxe especial para ele.

    
por 25.10.2011 / 21:45
fonte
8

Eu os uso quando determinada funcionalidade precisa ser aplicada a mais de um valor. Por exemplo, digamos que você tenha um objeto com uma propriedade chamada operationCode. Se o código for igual a 1, 2, 3 ou 4, você deseja startOperationX (). Se for 5 ou 6, você deseja startOperationY () e 7 startOperationZ (). Por que ter 7 casos completos com funcionalidade e quebras quando você pode usar fall-throughs?

Eu acho que é completamente válido em certas situações, especialmente se ele evitar 100 declarações if-else. =)

    
por 25.10.2011 / 21:26
fonte
8

Eu os usei ocasionalmente, acho que é sempre um uso apropriado - mas apenas quando incluído no comentário apropriado.

    
por 25.10.2011 / 21:30
fonte
7

Os casos de fall-through estão perfeitamente bem. Muitas vezes, acho que uma enumeração é usada em muitos lugares e, quando você não precisa diferenciar alguns casos, é mais fácil usar a lógica de fall-through.

Por exemplo (observe os comentários explicativos):

public boolean isAvailable(Server server, HealthStatus health) {
  switch(health) {
    // Equivalent positive cases
    case HEALTHY:
    case UNDER_LOAD:
      return true;

    // Equivalent negative cases
    case FAULT_REPORTED:
    case UNKNOWN:
    case CANNOT_COMMUNICATE:
      return false;

    // Unknown enumeration!
    default:
      LOG.warn("Unknown enumeration " + health);
      return false;
  }
}

Acho esse tipo de uso perfeitamente aceitável.

    
por 26.10.2011 / 05:41
fonte
6

Depende de:

  • sua preferência pessoal
  • padrões de codificação do seu empregador
  • a quantidade de risco envolvida

Os dois principais problemas associados a deixar um caso cair para o seguinte são:

  1. Isso torna o seu código dependente da ordem das declarações de caso. Esse não é o caso se você nunca cair, e isso adiciona um grau de complexidade que muitas vezes não é bem-vindo.

  2. Não é óbvio que o código de um caso inclua o código de um ou mais casos subsequentes.

Alguns lugares proíbem explicitamente a queda. Se você não trabalha em tal local, e se você está confortável com a prática, e se quebrar o código em questão não causará nenhum sofrimento real, então pode não ser a pior coisa do mundo. Se você fizer isso, certifique-se de colocar um comentário que chame a atenção por perto para avisar aqueles que vierem mais tarde (incluindo o futuro você).

    
por 25.10.2011 / 22:32
fonte
4

Aqui está um exemplo rápido (reconhecidamente incompleto (sem manuseio especial de ano bissexto)) de tornar a minha vida mais simples:

function get_julian_day (date) {
    int utc_date = date.getUTCDate();
    int utc_month = date.getUTCMonth();

    int julian_day = 0;

    switch (utc_month) {
        case 11: julian_day += 30;
        case 10: julian_day += 31;
        case 9:  julian_day += 30;
        case 8:  julian_day += 31;
        case 7:  julian_day += 31;
        case 6:  julian_day += 30;
        case 5:  julian_day += 31;
        case 4:  julian_day += 30;
        case 3:  julian_day += 31;
        case 2:  julian_day += 28;
        case 1:  julian_day += 31;
        default: break;
    }

    return julian_day + utc_date;
}
    
por 03.10.2016 / 18:57
fonte
3

Se eu sentir necessidade de ir de um caso para outro (raro, reconhecidamente), prefiro ser muito explícito e goto case , é claro, que pressupõe que seu idioma o apóie.

Como a queda é tão incomum e fácil de ignorar ao ler o código, eu sinto que é apropriado ser explícito - e um goto, mesmo que seja para um caso, deve se destacar como um dedão dolorido.

Ele também ajuda a evitar erros que podem ocorrer quando as declarações de caso são reordenadas.

    
por 25.10.2011 / 22:55
fonte