Pra mim que vim do javascript
onde o json é algo tão "banal", entender o funcionamento com Go foi um tanto quanto diferente.
O Go tem uma pegada muito grande com ponteiros e bytes, então, de primeiro momento, é meio cabuloso saber que uma variável que foi passada como parâmetro vai ter o retorno da função diretamente no local da memória em que ela foi alocada e por aí vai.
Em javascript
, uma estrutura do tipo:
{
"campo": "qualquer coisa",
"numero": 10
}
é entendível na hora, contudo, em Go, a coisa não é bem assim.
Bora ver um exemplo prático e eu vou detalhar coisa por coisa.
package main
import (
"encoding/json"
"fmt"
)
type Car struct {
Color string `json:"color"`
Model string `json:"model"`
}
func main() {
car := Car{"Black", "Lancer"}
b, err := json.Marshal(car)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(b))
}
Explicando:
package main
estou definindo que o conteúdo dese arquivo pertence ao pacote main
. Por exemplo, se eu tivesse uma estrutura
app
services
main.go
controllers
main.go
users.go
main.go
Eu poderia dizer que services/main.go
pertence ao pacote services
, portanto, package services
, controllers/main.go
e controllers/users.go
ao pacote controllers
e por aí vai. Mas enfim, a ideia aqui é explicar json com go, outros detalhes eu vou abordar em outro capítulo. Prossigamos ...
type Car struct {
Color string `json:"color"`
Model string `json:"model"`
}
Aqui eu estou "definindo o meu objeto". Não sei se seria a melhor comparação, mas sabe o Type
do typescript
? Quase isso! Diferença que aqui eu consigo passar esse cara como ponteiro e trabalhar diretamente nele.
func main() {
car := Car{"Black", "Lancer"}
// car := Car{
// Color: "Black",
// Model: "Lancer",
// }
...
Aqui eu to dizendo: cria a varíavel car e atribui à ela o tipo Car com os seguintes valores ....
Note que existem duas maneiras de atribuir uma struct à uma variável. Pode ser parecido como é em javascript
, ou passar os valores diretamente na struct
sem precisar inserir as chaves. Em structs
mais simples é até viável, mas pensa num negócio gigante passar os valores sem saber o que é o que.
Ah, só uma observação: isso :=
é diferente de =
.
No primeiro, eu estou criando a variável e reservando ela em memória, ou seja, dando vida à ela e lhe atribuindo um valor,
enquanto que no segundo, a variável já existe em memória e eu estou reatribuindo um valor à ela. 0.o
Continuando ...
Aqui o bicho pega
b, err := json.Marshal(car)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(b))
O go pode trazer mais de um retorno numa função. Uma espécie de tupla, por assim dizer.
E também em Go, as chamadas de funções geralmente são o nome do pacote e a função. No nosso exemplo, estamos chamando do pacote json
a função Marshal
.
A função Marshal
retorna dois resultados: um slice
de bytes (é praticamente um array mas sem limite como um array) e um erro. Como parâmetro, essa função espera uma variável do tipo struct
que no nosso caso é car
.
Logo após é feita a checagem pra garantir que não houve algum erro (lembrando que o foco aqui é json e não tratativas de erros, uso correto da linguagem nem nada).
E depois, por último, convertemos aqueles bytes em uma string para ser mostrado pelo Println
, nosso console.log
do Go
.
E pah, a saída que teremos vai ser
{"color":"Black","model":"Lancer"}
Outras observações cabulosas do Go:
Quando se define uma struct, as "chaves" dela, para serem lidas por qualquer função ou algo do tipo, precisam ser em letras maiúsculas. Portanto, se eu tivesse:
type Car struct {
color string `json:"color"`
model string `json:"model"`
}
a saída seria simplesmente
{}
uma vez que os atributos dessa struct
não foram exportados (implicitamente escrever iniciando em letra minúscula fala pro Go que o atributo daquela struct não é para ser exportado).
Mas fica estranho né, imagina uma api que esteja esperando esse objeto:
{
"color": "black",
"model": "Lancer"
}
mas estamos enviando "Color" e "Model" no body da request.
Para resolver isso, colocamos aquele json:"color"
na frente do atributo da struct
. Com isso estamos dizendo para o Go: Cara, a struct Car
tem o atributo Color
, então, internamente, a gente referencia Color
mas externamente, ou seja, se formos enviar esse json pra fora do programa ou vamos receber esse json de algum outro lugar, ele vai ter o campo "color" e não "Color".
É, isso é Go ...
Essa é a primeira parte, transformando uma struct em um json. Vamos ter a segunda parte onde vamos transformar um json em uma struct.
Te espero lá!!!
Top comments (0)