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)