Blog Nil e Null. Vixi! E agora?

Nil e Null. Vixi! E agora?

Nil e Null. Vixi! E agora? post thumbnail image

Em Delphi, lidar com referências a objetos é uma tarefa que parece simples à primeira vista, mas pode esconder armadilhas perigosas. Se você já se deparou com mensagens de erro ao acessar um objeto “nulo”, sabe o impacto que isso pode causar. E agora, como resolver? É uma boa ideia usar nil ou null para inicializar ou verificar variáveis? Será que existe um jeito mais seguro e elegante de lidar com isso?

Neste artigo, vamos explorar as diferenças entre nil e null, seus usos (ou falta deles), e como podemos aplicar boas práticas para evitar problemas futuros. A ideia aqui é deixar o código mais legível, seguro e fácil de manter. Então, vamos colocar a mão na massa e resolver essa dúvida de uma vez por todas!

O Problema com nil e null

Para quem programa em Delphi, é comum usar nil para inicializar ou verificar se um objeto está “vazio”. No entanto, essa prática pode gerar confusões e problemas em códigos mais complexos. Afinal, nil é apenas uma representação de ausência de referência, mas não indica contexto. Por outro lado, null é amplamente usado em bancos de dados para sinalizar a ausência de um valor, sendo um conceito diferente do nil no Delphi.

O grande problema surge quando utilizamos essas abordagens de forma indiscriminada, resultando em códigos difíceis de manter e propensos a erros. Como podemos melhorar isso?

O que é nil? Para que serve? Como funciona?

No Delphi, nil é uma constante especial usada para representar a ausência de referência em um ponteiro ou objeto. Ele é equivalente a dizer que algo está “vazio” ou “não inicializado”. Por exemplo, ao criar um objeto, você pode defini-lo como nil até que ele seja instanciado.

Uso do nil:

  • Indicar que um objeto ainda não foi criado.
  • Especificar que uma referência a ponteiro ou objeto foi liberada.
  • Verificar se um objeto ou ponteiro já foi instanciado ou ainda está “nulo”.

Como funciona:

O valor nil é internamente representado pelo endereço de memória 0. No momento em que você usa nil para um objeto, você está basicamente dizendo ao compilador que ele não deve apontar para nenhuma posição válida na memória.

Cuidados com nil:

  • Usar objetos sem verificar se estão atribuídos (Assigned) pode causar erros como Access Violation.
  • Liberar a memória de objetos com Free sem definir nil posteriormente pode gerar referências pendentes perigosas.

O que é null? Para que serve? Como funciona?

O termo null não é diretamente utilizado no Delphi como parte da linguagem, mas está intimamente relacionado a bancos de dados e sistemas externos. No contexto do Delphi, null é um valor usado para indicar a ausência de um dado ou valor desconhecido em operações com bases de dados.

Uso do null:

  • Representar a ausência de valor em campos de tabelas de banco de dados.
  • Trabalhar com frameworks como FireDAC, onde o valor null é atribuído a parâmetros ou campos vazios.

Como funciona:

No contexto de bancos de dados, null é um conceito que indica “não há dado aqui”. Ele não é o mesmo que um valor vazio ou zero, mas sim uma ausência completa de informação. Em Delphi, o uso de null é geralmente manipulado por bibliotecas de acesso a dados como FireDAC.

Exemplo de uso com FireDAC:

Cuidados com null:

  • Comparações diretas com null não funcionam. É necessário usar funções específicas, como IsNull.
  • Tratar valores null em consultas pode evitar erros, mas precisa de lógica específica para interpretar a ausência de dados.

Apesar disso, o Null também pode ser encontrado na linguagem. Veja:

No Delphi, Null é uma constante do tipo variante que representa um valor indefinido ou desconhecido. É frequentemente utilizada em operações que envolvem variantes, especialmente ao interagir com bancos de dados ou automação OLE, onde campos podem não ter valores atribuídos.

Uso do Null:

Atribuição a Variantes: Pode-se atribuir Null a uma variável do tipo Variant para indicar a ausência de valor.

Interação com Bancos de Dados: Ao trabalhar com bancos de dados, Null é utilizado para representar campos sem valor (NULL) nas tabelas.

Como funciona:

Null é uma constante predefinida no Delphi que retorna uma variante nula. Operações aritméticas ou lógicas envolvendo Null geralmente resultam em Null, e comparações com Null devem ser feitas usando funções específicas, como VarIsNull, pois comparações diretas podem não produzir os resultados esperados.


É importante diferenciar nil e Null no Delphi:

  • nil é utilizado para indicar a ausência de uma referência válida para objetos ou ponteiros.
  • Null é utilizado para representar a ausência de valor em variantes, especialmente em contextos de banco de dados.

Compreender essas distinções é fundamental para evitar erros comuns e garantir a robustez do seu código em Delphi.

Boas Práticas para Evitar nil e null

1. Utilize Objetos Padrão (Null Object Pattern)

#Dica do Mestre: O Null Object Pattern simplifica a lógica e evita exceções de acesso a objetos nulos.

    2. Centralize o controle das inicializações

    Isso evita confusões e garante que os objetos sejam corretamente configurados ao serem criados.

    3. Evite dependência excessiva de checagens de nil

    Melhora abordagem:

    4. Adote bibliotecas e frameworks de checagens de nil


      Participe da Comunidade no Telegram

      🚀 Quer continuar essa discussão e trocar ideias com outros desenvolvedores? Junte-se à nossa comunidade no Telegram! Lá, você pode comentar sobre o que achou deste artigo, tirar suas dúvidas e compartilhar suas experiências com Delphi e ainda discutir ou tirar suas dúvidas sobre os mais variados temas em uma comunidade com mais de 1.000 desenvolvedores.

      🔗 Clique aqui para entrar na comunidade

      Te vejo lá!

      Conclusão

      Evitar o uso excessivo de nil e null em Delphi é uma questão de design e manutenção de código. Com padrões como Null Object e ferramentas como Spring4D, você pode transformar o seu código em algo mais seguro, eficiente e elegante. Experimente essas práticas e veja como elas podem mudar sua forma de programar.

      Tem alguma dúvida ou dica para compartilhar? Deixe nos comentários, e até a próxima!

      2 thoughts on “Nil e Null. Vixi! E agora?”

      1. boa noite,
        conforme explicou e bem,
        o null está relacionado com base de dados,
        o null, no fundo, é um valor nulo, que não ocupa espaço no campo da base de dados,
        diferente de ter ou não um valor, imagine um booleano, ou é verdadeiro ou falso,
        mas você pode partir do principio que todos os nulos são falsos,
        esta é a grande vantagem!…
        sem ter que os definir como falsos, certo?
        logo, se quer que tenha um valor, pode ser feito um default no campo,
        tipo : inteiro/float=0, char/varchar/text=”, por aí…
        no entanto, considero isso uma má prática,
        uma vez que aplicar um default, você está a ocupar a base de dados, com nada…
        seja uma data, um booleano, um inteiro, um float ou um caractere.

        na minha opinião, isso deve ser tratado na query que é feita,
        o problema é que, em função da base de dados que estiver a fazer a query,
        a linguagem poderá ser diferente, também torna as querys mais complexas,
        por outro lado, a perfomance é incomparável e não tem que tratar nada no cliente.

        imaginem : se for MSSQL:
        select isnull(cliente_no,0) nocliente from clientes where isnull(cliente_no,0)>0;
        no delphi, não necessita validar nada, todos os clientes são carregados corretamente,
        já validamos isso na base de dados.
        eu pessoalmente, trato isso ao nível da base de dados.

        se for no postgres:
        select coalesce(cliente_no,0) nocliente from clientes where coalesce(cliente_no,0)>0;
        está feito, sem preocupações do lado do cliente e sem necessidade de qualquer validação,
        resolvido diretamente na query e o motor de base de dados que trate disso.

        se quer clean code, e se trabalha com base de dados, esqueça o tratamento do lado do delphi,
        eu trabalho com base de dados gigantes, milhões de registos….
        tenha ideia que se for um boolean, com um default false, num milhão de registos numa única tabela,
        você gasta + 1 GB, expanda isso por mais 10 campos e tem 10 gb, pense que tem um default em 100 tabelas e, vá fazendo as contas…o espaço, hoje em dia custa muito dinheiro e, depois tem que fazer backup, mais não sei quanto espaço a mais e por aí vai…

        se fizer uma api com : select * from clientes, vai trafegar mais um montão de bytes desnecessáriamente, perdendo perfomance e atrasando o processamento, por muito clean code que tenha no delphi.

        percam tempo a definir a base de dados independentemente do motor, não usem defaults, trabalhem melhor as querys, especialmente se trabalharem com muitos registos,
        a minha experiência diz que elas crescem e depois pode ser complexo, alterar tudo no motor e no delphi, já sabem, clean code em todo o lado…

      Deixe sua resposta

      O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

      Posts Relacionados