Fiz uma imersão em Go e neste post compartilho com vocês minhas primeiras impressões. Aproveito e também exponho meu plano de estudos que talvez ajude quem estiver dando seus primeiros passos na linguagem.
Já adianto: por que não fiz esta imersão antes???
Neste post há minhas primeiras impressões: leia da forma mais crítica possível, ok?
Meus objetivos
A plataforma Java não sai de mim e dificilmente sairá, mas há alguns requisitos para os quais ela ainda não é ideal quando precisamos implementar soluções que sejam:
- Nativas para realizar integrações de mais baixo nível.
- De rápida inicialização (para lambda functions, por exemplo).
- Baixíssimo consumo de memória e recursos computacionais.
- Baseadas em linha de comando (para tooling em alguns de nossos projetos).
- Que possa ser compiladas para diferentes plataformas (embarcados é um plus interessante aqui).
- Se for possível implementar APIs baseadas em HTTP, ótimo (é um plus).
Todos os pontos acima consigo hoje na plataforma Java (especialmente após o GraalVM), mas não é natural na plataforma ainda. Então nestes casos buscamos alternativas, dentre as quais uma que se mostrou bastante interessante foi Rust (escrevi a respeito aqui). É impossível não fazer comparações com ela neste post.
Meu plano de estudos
Comecei a imersão definindo os objetivos que me permitiram ter uma visão prática de Go:
- O primeiro é escrever uma ferramenta de linha de comando que seja realmente útil para mim. Então criei uma que gera arquivos no formato JSON tendo como entrada algumas planilhas que uso em meu dia a dia.
- O segundo foi escrever uma API REST usando como base de dados os arquivos gerados pelo primeiro projeto.
Com isto o primeiro objetivo me forneceu a segurança que eu precisaria para poder sair do core da linguagem e, assim, experimentar frameworks e bibliotecas mantidas pela comunidade e assim sentir (friso o termo “sentir” pois são primeiras impressões ainda) como as pessoas lidam com este ecossistema.
Planejo meus estudos com minha própria metodologia que pode ser lida neste link.
Bibliografia rápida e comentada
Optei por focar na documentação oficial para começar, clicando sobre o link “Learn” do site oficial (https://go.dev). Aqui você verá as três opções expostas no print abaixo:
Meu erro foi ter começado pela documentação (Documentation) e não pelo tour (Tour of Go). Se estiver tendo seu primeiro contato sugiro começar pelo Tour.
Começando pelo Tour of Go – https://go.dev/tour
Tem a profundidade de uma moeda mas te prepara para dar os primeiros passos na linguagem pois ao contrário da documentação oficial, é linear. É um destes tutoriais interativos nos quais há uma explicação do lado esquerdo e código para você experimentar do lado direito.
Em aproximadamente uma hora (no máximo duas se você estiver brincando com a linguagem no processo). Recomendo que você faça inteiro (preferencialmente experimentando ao máximo).
Há tradução para o Português do Brasil, mas se você sabe inglês recomendo que evite esta tradução pois encontrei algumas coisas como as expostas nos prints abaixo:
Caminho alternativo ao Tour of Go – vídeo
Não gosto de vídeos para estes primeiros contatos com linguagens mas a documentação oficial indica este vídeo (em inglês) cheio de chavões (musiquinha feliz, introdução enche linguiça…) que talvez possa te ajudar. Não é ruim, mas pessoalmente não gosto (me falta paciência).
Indo para a documentação oficial – https://go.dev/doc/
Após ter seguido os tutorias básicos (ao menos o interativo) a documentação oficial fornece o aprofundamento que precisava para poder entender os detalhes da linguagem que farão toda a diferença. Seguem aqui então os links da documentação que mais me ajudaram.
Um dos pontos fotes do Go é o modo como lida com concorrência. Dado que este é apenas seu primeiro contato e os projetos iniciais são bem simples, não irei tocar nestes assuntos (busque por “goroutines” ;) ).
O básico sobre módulos
Se você vêm do Java ou .net o conceito de pacotes do Go pode te parecer confuso: não por ser complexo, mas por ser simples. Então leia estes dois links na sequência:
- Tutorial: getting started – é um Hello World que vai ser usado adiante, faça só pra treinar.
- Tutorial: Create a Go Module – você vai criar seu primeiro módulo
- Getting started with multi-module workspaces – você definitivamente vai sentir falta de não conhecer o conceito de workspaces do Go quando for implementar seus projetos maiores (sofri um pouco com isto), então preste muita atenção neste link.
Organizando seu código
Você que vêm do Java vai sentir saudades do Maven em seu primeiro contato. Ao escrever sua primeira aplicação que envolva mais de um arquivo esta saudade irá apertar. Este link (How to Write Go Code) te ensina como seu código fonte deve estar organizado e também tornará mais clara a distinção entre módulo (module) e pacote (package). (um módulo contém pacotes ;) )
Outro link que vai ajudar é este: Organizing a Go module.
Effective Go e FAQ
Vai te ajudar bastante também conhecer as convenções adotadas pela linguagem. O link “Effective Go” me ajudou a responder diversas dúvidas simples mas que podem tomar bastante seu tempo, tais como: quando uso ponto e vírgula? Como lido com erros? E estas funções que retornam mais de um valor como resultado?
O FAQ também tem coisas úteis. Não acho que você deva lê-lo de cabo a rabo, mas pelo menos dar uma passada de olhos pelo índice já ajuda a descobrir dúvidas que você ainda não sabe que tem.
Biblioteca padrão – https://pkg.go.dev/std
Em diversos momentos você lerá na documentação que a biblioteca padrão é bastante rica e bla bla bla. Então é interessante ver os módulos que compõem a biblioteca pra se ter uma noção do que de fato está ali. E tem coisas muito legais, tais como funções para se gerar HTML, JSON, funções de hash, logging, testes, etc.
Fica bem claro que é possível, por exemplo, escrever uma aplicação web sem um framework externo.
Material para desenvolvimento web
Até este momento tudo o que expus satisfaz o primeiro objetivo do meu plano de estudos. Para o segundo objetivo (a API REST) segue aqui algum material com avisos.
Frameworks
Todos que vi até agora achei muito parecidos, me lembrando muito micro frameworks como Flask, por exemplo, e pelo que pude aprender até agora todos usam inclusive como base a biblioteca padrão do Go para tal.
Gin Web Framework – https://gin-gonic.com/
O framework que adotei para o segundo objetivo foi o Gin e por uma razão bem boba: segui o tutorial que estava presente na própria documentação oficial da linguagem que pode ser acessado neste link: Tutorial: Developing a RESTful API with Go and Gin.
A documentação do Gin é péssima, e você pode acessar neste link. Você encontrará um quickstart extremamente básico com um “hello world” e não muito mais além disto.
Infelizmente os autores do framework acreditam que uma boa forma de se ensinar é a partir de exemplos, então você terá de navegar por eles, que podem ser vistos neste link.
Um vídeo interessante
Minha impressão de que os frameworks que vi eram basicamente sempre a mesma coisa se confirmou neste vídeo: https://www.youtube.com/watch?v=JECZTdEJnOI
Primeiras impressões
Ferramentas
Não senti falta de nada e até agora tudo o que usei achei excelente. Tenho usado o VS Code como IDE e os plugins recomendados funcionam perfeitamente.
Para facilitar minha vida instalei Go usando o asdf com o plugin golang. O Asdf nos permite ter instalações concorrentes de basicamente todas as ferramentas de desenvolvimento que você pode imaginar. Se ainda não conhece, recomendo que leia este tutorial que escrevi a respeito no site da itexto.
As ferramentas de linha de comando do Go nos permitem também fazer tudo o que precisamos é como se o Maven tivesse um filho com o Cargo do Rust:
- Gerenciar dependências (muito parecido com o Cargo do Rust).
- Compilar os projetos (óbvio!)
- Executar testes
- Criar módulos
- Buscar erros no projeto
- Instalar ferramentas adicionais (há várias!)
A velocidade do compilador impressiona. É muito rápido.
A linguagem
Orientação a objetos?
Aqui percebi que com o tempo realmente fui me tornando uma pessoa viciada em orientação a objetos (Kico de 15 anos atrás olha pra mim e diz: não te disse???). Go não é orientado a objetos tal como estamos acostumados no caso do Java ou C# por exemplo (este vídeo é interessante).
Há sim objetos, mas não há classes ou herança: a norma claramente é programação procedural aqui. E sabe de uma coisa? Confesso que senti alívio enquanto escrevia meus mini projetos e via como é possível escrever código muito mais simples para estes contextos (aplicações simples) sem orientação a objetos (o Kico de dez anos atrás também me cutucou aqui).
(Orientação a Objetos não é uma boa prática de desenvolvimento: é um paradigma de programação que tem seu lugar de aplicação. Infelizmente isto não é claro pra muita gente ainda hoje…)
Há polimorfismo, e o conceito de interfaces aqui é muito interessante. É vista como algo implícito (você não precisa daquelas instruções implements
). Duck typing basicamente.
Simples!
Não é exagero dizer que se você terminar o Tour of Go vai ter o ferramental necessário para implementar tudo o que me propus nesta imersão. A linguagem é realmente muito simples e torna simples coisas que são complexas em outras.
- Um modelo de strings simples. Não é algo complicado como o que temos em C ou ainda mais complicado como o que temos em Rust (este vídeo sobre strings em Rust é muito útil).
- Você tem ponteiros que são fáceis de entender.
- Um esquema de pacotes e módulos simples de entender (ao contrário do que temos em Rust que apesar de poderoso leva um tempo até pegar o jeito).
- Um modelo de dados muito básico: os tipos numéricos que precisamos (inclusive unsigned, algo que sempre senti muita falta no Java (pense em integrações de baixo nível que você vai me entender), um único tipo de string, structures (que só entraram no Java recentemente), maps, slices (como listas) e ponteiros (que já falei)
A sintaxe também é muito simples. Me lembra Groovy, mas ainda mais simples, o que me leva a outro ponto importante.
Curva de aprendizado
Em um dia usando apenas a documentação oficial consegui cumprir os dois objetivos que me propus sem nenhum conhecimento prévio sobre a linguagem. Importante: estou falando sobre mim, que atuo na área desde 1996 e já passei por diversas linguagens e ambientes de desenvolvimento, mas normalmente quando vou aprender algo novo do zero, com o tempo que tenho disponível hoje, leva pelo menos uma semana.
É impossível para mim não fazer aqui uma comparação com Rust. Não acredito que em uma semana você consiga se tornar realmente produtivo na linguagem, mas com Go, se for para desenvolver inicialmente ferramentas como o primeiro objetivo que me propus, acredito que sim.
E é muito mais fácil treinar uma equipe em Go que em Rust por outra razão: a simplicidade da documentação também. Experimente tentar aprender Rust pelo material indicado pela comunidade (o livro “The Rust Programming Language”) e compare com o guia que expus neste post.
(Antes que chegue um fanático aqui: não estou dizendo que Rust seja ruim, mas sim que sua curva de aprendizado é um problema real)
Testes
Assim como Rust, Go também trás as funcionalidades necessárias para que você possa escrever seus testes unitários e integrados. Tem inclusive recursos bem legais como por exemplo a escrita de benchmarks, fuzzing (passagem de valores aleatórios para funções) e algumas outras funcionaliddes.
Se você ler a documentação oficial encontrará links como este (Add a test no Tutorial dos módulos que indico no início). Mas sabe o que não está incluído nas bibliotecas? Asserções! Você terá de usar projetos como este para que sejam incluídas em seus testes.
Aqui está o ink para a documentação do módulo testing, que é o oficial para a execução de testes.
Acesso a bases de dados relacionais
Na biblioteca padrão o módulo database (dividido nos pacotes sql e sql/driver) me chamaram a atenção. Temos ali padronizadas todas as interfaces a serrem seguidas pelos fornecedores de bases de dados relacionais usando um modelo muito parecido com o que temos no JDBC do Java.
Este é um diferencial importante em relação ao Rust que, até onde sei, ainda não tem algo similar padronizado na própria linguagem. E por que isto é importante? Por que facilita muito a adoção da linguagem no ambiente corporativo no qual não raro o SGBD relacional é Rei.
Começando
É raro eu ter uma primeira impressão tão positiva de uma linguagem de programação (a última foi Groovy): não acredito que seja a primeira impressão que fica, mas sim a última, quando os problemas reais vão se mostrando conforme desafios maiores surgem.
A simplicidade da linguagem associada a uma biblioteca padrão que me fornece tudo o que preciso pra começar a trabalhar, assim como um ferramental que já vêm praticamente pronto após a instalação colocou Go pra mim como uma alternativa muito interessante para os cenários que mencionei no início do post.
Na minha opinião, quanto menor for o tempo que você tiver para treinar sua equipe em uma linguagem para estes cenários, maior a probabilidade de sua escolha ser Go ao invés de Rust.
Gostei muito do texto e o achei bem preciso. O grande valor da golang é o runtime diminuto, facilidade do deploy e simplicidade da linguagem que você mencionou todos. A linguagem agrega valor a um time de desenvolvimento pela baixa curva que ela apresenta, reduzindo os custos de conseguir um time especialista.
Um ponto que observei e gostaria de colocar um contra-ponto é sobre herança. Golang alcança herança por composição, e a linguagem é capaz de fazer seus objetos entenderem e se relacionarem como tal.
Obrigado Júlio, vou dar uma lida sobre esta questão da herança por composição, pois como é meu primeiro contato, ainda é tudo muito novo pra mim, valeu!
É uma funcionalidade bem legal. Chama embedding. Você anexa sua struct no corpo da outra, e a nova automaticamente absorve as informações da anterior. Funciona com interfaces também, o que deixa a coisa mais interessante ainda.
https://eli.thegreenplace.net/2020/embedding-in-go-part-1-structs-in-structs/
Essa linguagem é maravilhosa! Sem querer bancar o fanboy, acho que ela reúne um bocado dos pontos positivos das outras: desempenho (C, Rust), praticidade e curva de aprendizado (Python, Ruby), segurança de tipos em tempo de compilação (C, Java, C#). Mas também, sendo criada dentro de uma Big Tech com recursos e pessoal altamente qualificado, isso é o mínimo que podemos esperar.
Também to achando bem legal e, mais interessante: algo que pode abrir portas.
Java abriu um Universo pra mim, Rust abriu uma portinha interessante pra embarcados e sistemas que requerem um consumo menor de memória.
Problema: Rust não é amigável. Go é um Rust amigável que supre pra mim alguns pontos que Java não atende hoje.
Desempenho da rust e da c já tem uma diferencinha(ordens de magnitude, 🙂)
A vantagem da go e ter um runtime diminuto em relação a c#, Java, python, etc. Enquanto c e rust não têm nenhum.
Complementando, para não dizer que tudo é flores: não ter um try-catch e ter que ficar verificando erro com if linha a linha é um troço de lascar. Mas não suplanta as qualidades.
To nessa trilha também.
Faz um tempo que venho querendo estudar, comecei, parei e desta vez levando mais a sério.
De fato, é empolgante, venho do “mundo Java” e quando vi o Go pela primeira vez, em 2019, pensei “Pq n o Go?! Pq o mercado ainda n enxergou isso? (como deveria)”, eu tinha achado tudo muito simples de fazer, intuitivo, multi plataforma, rápido, leve… e hj, estudando, o que vi até agora, só confirma as minhas primeiras impressões, curtindo demais!
Let’s Go ahead!
Eu tô pensando seriamente em alguns próximos projetos ir do Spring Boot pro Go
Dá para migrar tranquilo, e você ganha Green threads de graça.
Sempre trabalhei como analista de software e suporte. E no momento estou procurando oportunidades como Dev, estava focado em python. Fiz alguns projetos em python, mas quando entrei na parte de async sofri bastante, ai resolvi começar a escrever a parte de async em Go para ver como era, e em pouquíssimo tempo resolvi todas as questões de async, até que migrei todo o projeto para essa linguagem e consegui uma performance absurda.
Muito bom. Não sei eu não acho Go legal. Os motivos devem ser sentimentais kkk!
Não sei explicar
Também passei anos assim aí um dia resolvi experimentar tae e… minha percepção mudou muito!
Eu uso golang profissionalmente desde 2014. Meu norte sempre foi escolher linguagens seguras e que gerassem código nativo do processador alvo. Em 2014 as mais seguras que se encaixavam nesse grupo eram c++11 e pascal, até conhecer golang. A versão era 1.5 ainda. C++11 não era tão seguro e dependia do programador definitivamente aceitar o draft 11. Meu emprego na época usava c++95. Os bugs gerados eram os mais bizarros possíveis.