Interfaces

Golang é realmente, do meu ponto de vista, uma das melhores linguagens atualmente no mercado, que traz atributos indispensáveis a um bom projeto de engenharia, gosto de compara-la a projetos como a caneta bic por exemplo, minimalista e funcional. Obviamente, como tudo na vida, não é uma bala de prata, não serve a todos os propósitos, uma vez que temos mais propósitos do que ferramentas, porem creio atender muito mais do que bem, diria até de forma excelente a tudo que se propõe.
Apesar de muitas qualidades algumas coisas me incomodam um pouco na linguagem, até mesmo por vezes, pela minha própria falta de conhecimento, por exemplo a forma como uma struct é escrita na saída padrão quando fazemos algo como fmt.Println(struct). Buscando usar as limitações como combustível vamos estudar as standard interfaces de go e melhorar a forma como as structs são exibidas em tela.
As interfaces presentes na standard library são um ponto muito forte da linguagem, com elas podemos acrescentar características aos nossos tipos e torna-los mais poderosos. Interfaces são contratos que especificam o comportamento, ou seja, os métodos que um tipo deve possuir para assinar o tal contrato.
Go traz em sua biblioteca padrão varias interfaces que podemos implementar, por exemplo a interface Stringer presente no package fmt
type Stringer interface {
String() string
}
Esta interface descreve o comportamento de transformação em string e é usada no package fmt no método Println por exemplo, sendo assim, se um tipo que definimos possui o método String, quando passado ao Println o método será invocado e a string retornada será escrita na tela, nos permitindo desta forma controlar como um objeto será interpretado pelo package fmt.
Na prática
Vamos criar um tipo para usarmos como exemplo e implementarmos a interface
type Pessoa struct {
Name string
Age int
Document string
}
O tipo Pessoa descrito acima é completamente arbitrário, podemos usar aqui qualquer tipo que faça sentido no contexto.
Conforme vimos acima as interfaces permitem adicionarmos comportamentos aos nossos objetos, então para seguirmos o exemplo, vamos implementar no nosso objeto a interface Stringer , para tal basta criarmos um método chamado String que retorne uma string no nosso tipo Pessoa
func (p Pessoa) String() string {
b, err := json.Marshal(p)
if err != nil {
panic(err)
}
return string(b)
}
Desta forma quando fizermos algo como fmt.Println(pessoa) será apresentado um json com os valores de Pessoa Exemplo completo.
Uma ideia que podemos inferir com base no exemplo acima é o fato de não precisarmos de uma palavra reservada para definir que estamos implementando determinada interface, isso acontece automaticamente quando temos o método presente no tipo em questão, isso é chamado de duck typing, e este ultimo ponto nos permite também, inferir que em go podemos implementar mais de uma interface nos tipos.
Como vimos as interfaces fornecem uma camada de comunicação entre packages e objetos, descrevendo comportamentos esperados que devemos possuir e permitindo-nos implementar cada um destes comportamentos de forma particular para cada objeto.
Go tem muitas outras interfaces na sua biblioteca padrão que podem nos ajudar a implementar comportamentos esperados pela linguagem, tornando nossa vida mais fácil e simples e explora-las é uma excelente forma de se aprofundar na linguagem.






![[Repost] Código limpo precisa também ser simples](https://cdn.hashnode.com/res/hashnode/image/upload/v1671555713609/v8SIJtHTn.jpeg)