Sobrecarga e sobrescrita de operadores

Sumário

Neste post nós vamos discutir sobre:

  • O que é um operador.
  • O que é sobrecarga e sobrescrita de operadores.
  • Como implementar sobrecarga e sobrescrita de operadores.

O que é um operador?

Operadores são símbolos especiais que utilizamos para realizar verificações, mudanças e combinação de valores.

O Swift suporta a maioria dos operadores herdados do C, mas existem alguns operadores que também são comuns em outras linguagens, como o ++, que foram descontinuados na terceira versão do Swift.

Apesar disto, a linguagem fornece alguns operadores interessantes como o de intervalo fechado () e intervalo aberto (..<).

O que é sobrecarga e sobrescrita de operador?

Podemos definir sobrecarga de operador como a implementação do operador com novos argumentos, ou seja, é quando nós acrescentamos mais funcionalidade a um operador.

Esta funcionalidade da linguagem abre várias possibilidades para os desenvolvedores, porém é muito importante que uma reflexão seja feita. Muitas vezes se utiliza a sobrecarga para facilitar a nossa vida, porém temos que falar sobre legibilidade de código.

Nós já temos uma concepção do uso desses operadores e um comportamento muito diferente pode causar uma grande confusão para outros desenvolvedores da sua equipe de trabalho ou até mesmo que possa ter que manter seu código posteriormente. Isso é extremamente importante quando nós falamos sobre repositórios de código aberto, já que muitas vezes eles são mantidos por uma grande quantidade de desenvolvedores e utilizados por novos desenvolvedores durante a sua introdução no mundo da programação.

Em resumo temos que balancear legibilidade com a facilidade que esta funcionalidade traz para os desenvolvedores.

Implementando sobrecarga e sobrescrita de operadores.

Vamos utilizar um Swift Playground para testar todos os modos de sobrecarga de operadores.

A primeira maneira que iremos discutir é a sobrecarga global de operadores. Mas inicialmente precisamos falar que todos os operadores são declarados globalmente, quando eu falo operador não é necessariamente a implementação, mas o operador em si. Sabendo disso, vamos trabalhar a implementação de um operador.

Quando trabalhamos globalmente nós podemos acrescentar uma nova assinatura para o operador dando uma nova funcionalidade para ele, porém não conseguimos sobrescrever o seu funcionamento.

Quando trabalhamos nós podemos acrescentar uma nova assinatura ao operador, atribuindo-lhe (dando-lhe) uma nova funcionalidade, entretanto não conseguimos sobrescrever o seu funcionamento.

Para exemplificar faremos um exemplo onde vamos fazer a sobrecarga do operador + para poder somar um Int com um Double. Nós sabemos que Swift é uma linguagem fortemente tipada, então isso não seria possível originalmente. Porém se você colocar o código abaixo em um Swift Playground você verá que tudo funcionará normalmente.

O exemplo acima tem alguns problemas relacionados ao que comentamos anteriormente: legibilidade. A linguagem nativamente não da suporte a essa operação e ela pode levar o desenvolvedor a ter uma visão equivocada do funcionamento do Swift, além de poder transmitir um entendimento errado já que um novo desenvolvedor que está trabalhando nesse código pode entender que n1 e n2 são do mesmo tipo.

Podemos ter alguns bons exemplos quando trabalhamos com CGRect, CGSize e CGPoint. Podemos sobrecarregar o operador de adição para fazer com que CGRect e CGSize/CGPoint possam ser somados, tornando o código mais fluido.

Sobrecarga do operador + e += para facilitar a edição de um CGRect

Caso sua aplicação trabalhe bastante com a manipulação de CGRect, CGPoint e CGSize essa sobrecarga pode facilitar bastante e torna seu código mais limpo. Neste exemplo estamos explorando a sobrecarga de operadores de modo mais especializado, ou seja, apenas esse tipo vai ter esse comportamento.

Para finalizar, devo salientar que, ao utilizarmos extensions para modificar o comportamento de operadores também podemos realizar a sobrescrita de um operador. Quando fazemos isso nós modificamos como a implementação padrão do operador funciona.

Não esqueça que nestes casos é necessário ter ainda mais atenção na relação facilidade vs legibilidade. (;

Referências

--

--