Diferença entre “pré-condição” e “afirmar” com rapidez?

105

Qual é a diferença entre precondition(condition: Bool, message: String)e assert(condition: Bool, message: String)em Swift?

Ambos parecem iguais para mim. Em que contexto devemos usar um em vez do outro?

Chao Ruan
fonte

Respostas:

125

asserté para verificações de integridade durante o teste, enquanto preconditioné para proteger contra coisas que, se acontecerem, significariam que seu programa não poderia prosseguir razoavelmente.

Assim, por exemplo, você pode colocar um assertem algum cálculo com resultados razoáveis ​​(dentro de alguns limites, digamos), para descobrir rapidamente se há um bug. Mas você não gostaria de enviar com isso, uma vez que o resultado fora do limite pode ser válido, e não crítico, portanto, não deve travar seu aplicativo (suponha que você estava apenas usando-o para exibir o progresso em uma barra de progresso).

Por outro lado, verificar se um subscrito em uma matriz é válido ao buscar um elemento é a precondition. Não há próxima ação razoável para o objeto de matriz executar quando solicitado por um subscrito inválido, pois ele deve retornar um valor não opcional.

Texto completo dos documentos (tente clicar em opções asserte preconditionno Xcode):

Condição prévia

Verifique uma condição necessária para avançar.

Use esta função para detectar condições que devem impedir o programa de prosseguir, mesmo no código de remessa.

  • Em playgrounds e builds -Onone (o padrão para a configuração de Debug do Xcode): se for conditionavaliado como falso, interrompe a execução do programa em um estado depurável após a impressão message.

  • Em compilações -O (o padrão para a configuração de lançamento do Xcode): se for conditionavaliado como falso, interrompe a execução do programa.

  • Em -Ounchecked constrói, conditionnão é avaliado, mas o otimizador pode assumir que ele iria avaliar a true. O não cumprimento dessa suposição em compilações -Ounchecked é um erro de programação sério.

Afirmar

O estilo C tradicional afirma com uma mensagem opcional.

Use esta função para verificações de integridade internas que estão ativas durante o teste, mas não afetam o desempenho do código de remessa. Para verificar o uso inválido em compilações de lançamento; veja precondition.

  • Em playgrounds e builds -Onone (o padrão para a configuração de Debug do Xcode): se for conditionavaliado como falso, interrompe a execução do programa em um estado depurável após a impressão message.

  • Em builds -O (o padrão para a configuração de lançamento do Xcode), conditionnão é avaliado e não há efeitos.

  • Em -Ounchecked constrói, conditionnão é avaliado, mas o otimizador pode assumir que ele iria avaliar a true. O não cumprimento dessa suposição em compilações -Ounchecked é um erro de programação sério.

Velocidade da velocidade do ar
fonte
2
"Mas você não gostaria de enviar com isso, uma vez que o resultado fora do limite pode ser válido, e não crítico, então não deve travar seu aplicativo", isso é muito vago para mim. Você pode incluir um exemplo exato? Talvez algum código.
Mel
2
Respondendo à sua pergunta, eu pessoalmente uso asserts para pegar coisas que simplesmente não deveriam acontecer em meu build enquanto estou escrevendo e testando. Imagine uma instrução de guarda lendo JSON onde data["name"]não existe, mas deveria. Ter uma declaração dentro do guarda ... outro {} me ajudaria a detectar meu erro ao travar e me trazer ao problema. Da mesma forma, se esse código estivesse em produção, o assert não travaria o programa e qualquer código de backup que eu usei ( return nil) assumiria.
Alec O de
1
Você não deveria verificar o índice e não fazer nada em vez de travar o aplicativo inteiro?
Iulian Onofrei
Sim, você deve verificar o índice, mas todo mundo escorrega às vezes, e usar asserts o ajuda a perceber que deveria ter verificado o índice quando se esqueceu.
Victor Engel
90

Achei afirmações do Swift - o manual que faltava pode ser útil

                        debug   release   release
function                -Onone  -O       -Ounchecked
assert()                YES     NO        NO
assertionFailure()      YES     NO        NO**
precondition()          YES     YES       NO
preconditionFailure()   YES     YES       YES**
fatalError()*           YES     YES       YES

E de discussões interessantes sobre o Swift Evolution

- assert: verificar se há erros internos em seu próprio código

- pré-condição: para verificar se seus clientes forneceram argumentos válidos.

Além disso, você precisa ter cuidado com o que usar, consulte assertionFailure e Nível de otimização

onmyway133
fonte
Você pode explicar a diferença entre o próprio código e o cliente? Quanto ao cliente, você quer dizer inserir números onde um String é esperado? Isso não deveria ser tratado com algum tratamento de erro simples?
Mel
@Honey Acho que ele está se referindo aos argumentos / resultados da chamada de API de rede ou dos próprios plug-ins do cliente.
Chen Li Yong
Cliente seria alguém usando seu código, digamos que você está escrevendo uma biblioteca e um programador passa dados inválidos. Você não gostaria de continuar normalmente, pois isso pode ser considerado um grave erro de programação. Você provavelmente nunca deve travar em dados inválidos de API de rede, pois isso é muito inútil para o usuário.
bompf
@ onmyway133: Do Xcode QuickHelp, eu acho precondition()e preconditionFailure()está tendo os mesmos comportamentos . A diferença entre essas funções é: preconditionprecisa de uma condição dentro, enquanto preconditionFailureapenas joga fora.
nahung89
12

O preconditionestá ativo no modo de liberação, portanto, quando enviar seu aplicativo e a condição prévia falhar, o aplicativo será encerrado. Assertfunciona apenas no modo de depuração como padrão.

Encontrei esta ótima explicação quando usá-lo no NSHipster:

Asserções são um conceito emprestado da lógica clássica. Em lógica, asserções são declarações sobre proposições dentro de uma prova. Na programação, as asserções denotam as suposições que o programador fez sobre o aplicativo no local onde foram declaradas.

Quando usadas na capacidade de pré-condições e pós-condições, que descrevem as expectativas sobre o estado do código no início e no final da execução de um método ou função, as asserções formam um contrato. As asserções também podem ser usadas para impor condições em tempo de execução, a fim de evitar a execução quando certas condições prévias falham.

Greg
fonte
As asserções podem ser habilitadas e desabilitadas usando um sinalizador do compilador; eles podem estar ativos no código enviado.
Pétur Ingi Egilsson
6

condição prévia

func precondition(condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String = default, file: StaticString = default, line: UWord = default)

Verifique uma condição necessária para avançar.

  1. Use esta função para detectar condições que devem impedir o programa de prosseguir, mesmo no código de remessa.
  2. Em playgrounds e builds -Onone (o padrão para a configuração de Debug do Xcode): se a condição for avaliada como falsa, pare a execução do programa em um estado depurável após imprimir a mensagem.
  3. Em compilações -O (o padrão para a configuração de lançamento do Xcode): se a condição for avaliada como falsa, pare a execução do programa.
  4. Em compilações -Ounchecked, a condição não é avaliada, mas o otimizador pode assumir que seria avaliada como verdadeira. O não cumprimento dessa suposição em compilações -Ounchecked é um erro de programação sério.

afirmar

func assert(condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String = default, file: StaticString = default, line: UWord = default)

O estilo C tradicional afirma com uma mensagem opcional.

  1. Use esta função para verificações de integridade internas que estão ativas durante o teste, mas não afetam o desempenho do código de remessa. Para verificar o uso inválido em compilações de lançamento; veja a pré-condição.

  2. Em playgrounds e builds -Onone (o padrão para a configuração de Debug do Xcode): se a condição for avaliada como falsa, pare a execução do programa em um estado depurável após imprimir a mensagem.

  3. Em compilações -O (o padrão para a configuração de versão do Xcode), a condição não é avaliada e não há efeitos
  4. Em compilações -Ounchecked, a condição não é avaliada, mas o otimizador pode assumir que seria avaliada como verdadeira. O não cumprimento dessa suposição nas compilações -Ounchecked é um erro de programação sério
13º fantasma
fonte