Oi.

Falei um pouco sobre Go e Clean Code em alguns meetups e na última Gophercon Brasil em 2019 (slides aqui) e agora estou quebrando essa apresentação em uma série de posts, começando com esse, para explicar que tipo de código é considerado limpo em Go. A motivação é dividir um pouco após anos de escrita de código em Go sobre as práticas consideradas boas / ruins.

Minha opinião modesta é que codigo limpo é mais do que uma série de Design Patterns ou princípios SOLID. Focamos muito nessas coisas e às vezes esquecemos em como escrever código que é facil de ser compreendido por outras pessoas que sabem programar nessa linguagem. Então eu sempre começo pelo styleguide da linguagem.

Eu tive muita dificuldade quando descobri que nomes de variáveis em Go devem ser pequenos ao invés de grandes. Reclamei um pouco com meus amiguinhos de trabalho, disse por aí que era um absurdo e muito estúpido. Eu estava sofrendo pelo fato de que sempre, sempre, desde que eu tinha lá meus quinze anos de idade e estava aprendendo a escrever código, meus professores me falaram pra escrever nomes que façam sentido e sejam descritíveis. Exemplos sempre saem de um livro de Java com um nome bastante descritivo para um método.

Quando você vê as notas de Rob Rike sobre seu estilo de programação, ele pontua que: “Tamanho não é virtude de um nome; clareza de expressão é.” (na seção Variable names).

Demorei um tempo pra perceber que nomes que fazem sentido e são descritíveis podem ser pequenos. E às vezes, quando você combina essas coisas seu código sai melhor.

Fazemos isso em outras linguagens mais do que imaginamos.

199
200
201
for i := 0; i < 10; i++ {
    sum += i
}

Nesse exemplo em particular, i é um nome bom para a variável index, enquanto sum na realidade é pequeno o suficiente para que não vire s.

Quando os Code Review comments de Go falam que você deve preferir c a lineCount, significa que esse código…

199
200
201
202
203
204
205
206
func countLines() int {
    // do stuff
    var linesCount int
    for i := 0; i < lines; i++ {
        linesCount += 1
    }
    return linesCount
}

não é mais legível do que este…

199
200
201
202
203
204
205
206
func countLines() int {
    // do stuff
    var c int
    for i := 0; i < lines; i++ {
        c += 1
    }
    return c
}

Por quê?

No dois casos, i e c são variáveis que vivem pouco. Seu escopo é pequenininho, limitado, o bloco de código em que são usadas é curto. Você vê aonde termina. Você não precisa descer muito a sua tela pra ler.

Numa regra mais geral, suas variáveis devem ter nomes que vão crescer de acordo com o escopo utilizado por elas. Não dê a louca e use c ao invés de lineCount em uma variável de pacote.

E fuja de escopos grandes - mas é um assunto pra um próximo post.

Ate mais :)

Links de referência