Respostas:
Para imprimir o nome dos campos em uma estrutura:
fmt.Printf("%+v\n", yourProject)
Do fmt
pacote :
ao imprimir estruturas, o sinalizador de adição (
%+v
) adiciona nomes de campos
Isso supõe que você tenha uma instância do Project (em ' yourProject
')
O artigo JSON e Go fornecerá mais detalhes sobre como recuperar os valores de uma estrutura JSON.
Esta página Ir por exemplo fornece outra técnica:
type Response2 struct {
Page int `json:"page"`
Fruits []string `json:"fruits"`
}
res2D := &Response2{
Page: 1,
Fruits: []string{"apple", "peach", "pear"}}
res2B, _ := json.Marshal(res2D)
fmt.Println(string(res2B))
Isso imprimiria:
{"page":1,"fruits":["apple","peach","pear"]}
Se você não tiver nenhuma instância, precisará usar reflexão para exibir o nome do campo de uma determinada estrutura, como neste exemplo .
type T struct {
A int
B string
}
t := T{23, "skidoo"}
s := reflect.ValueOf(&t).Elem()
typeOfT := s.Type()
for i := 0; i < s.NumField(); i++ {
f := s.Field(i)
fmt.Printf("%d: %s %s = %v\n", i,
typeOfT.Field(i).Name, f.Type(), f.Interface())
}
Quero recomendar go-spew , que de acordo com o github "Implementa uma impressora bonita e profunda para estruturas de dados Go para ajudar na depuração"
go get -u github.com/davecgh/go-spew/spew
exemplo de uso:
package main
import (
"github.com/davecgh/go-spew/spew"
)
type Project struct {
Id int64 `json:"project_id"`
Title string `json:"title"`
Name string `json:"name"`
Data string `json:"data"`
Commits string `json:"commits"`
}
func main() {
o := Project{Name: "hello", Title: "world"}
spew.Dump(o)
}
resultado:
(main.Project) {
Id: (int64) 0,
Title: (string) (len=5) "world",
Name: (string) (len=5) "hello",
Data: (string) "",
Commits: (string) ""
}
meus 2 centavos seriam usados json.MarshalIndent
- surpreso que isso não seja sugerido, pois é o mais direto. por exemplo:
func prettyPrint(i interface{}) string {
s, _ := json.MarshalIndent(i, "", "\t")
return string(s)
}
nenhum departamento externo e resulta em uma saída bem formatada.
"\t"
com " "
se você quiser recuo espaço em vez
Eu acho que seria melhor implementar uma longarina personalizada se você quiser algum tipo de saída formatada de um struct
por exemplo
package main
import "fmt"
type Project struct {
Id int64 `json:"project_id"`
Title string `json:"title"`
Name string `json:"name"`
}
func (p Project) String() string {
return fmt.Sprintf("{Id:%d, Title:%s, Name:%s}", p.Id, p.Title, p.Name)
}
func main() {
o := Project{Id: 4, Name: "hello", Title: "world"}
fmt.Printf("%+v\n", o)
}
p = Project{...}
fmt.Printf("%+v", p)
fmt.Printf("%#v", p) //with type
fmt.Printf(%#v, p)
, Atira-me main.struct
com struct type
o que é a diferença entre "%#v"
e "%+v"
@cokebol
Como alternativa, tente usar esta função PrettyPrint()
// print the contents of the obj
func PrettyPrint(data interface{}) {
var p []byte
// var err := error
p, err := json.MarshalIndent(data, "", "\t")
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("%s \n", p)
}
Para usar isso, você não precisa de pacotes adicionais, com exceção de fmt
e encoding/json
apenas uma referência, ponteiro ou literal da estrutura que você criou.
Para usar apenas pegue sua estrutura, inicialize-a no pacote principal ou em qualquer que seja o pacote e passe-o para PrettyPrint()
.
type Prefix struct {
Network string
Mask int
}
func valueStruct() {
// struct as a value
var nw Prefix
nw.Network = "10.1.1.0"
nw.Mask = 24
fmt.Println("### struct as a pointer ###")
PrettyPrint(&nw)
}
Sua saída seria
### struct as a pointer ###
{
"Network": "10.1.1.0",
"Mask": 24
}
Brinque com o código aqui .
Eu gosto de lixo .
De seu leia-me:
type Person struct {
Name string
Age int
Parent *Person
}
litter.Dump(Person{
Name: "Bob",
Age: 20,
Parent: &Person{
Name: "Jane",
Age: 50,
},
})
Sdump
é bastante útil em testes:
func TestSearch(t *testing.T) {
result := DoSearch()
actual := litterOpts.Sdump(result)
expected, err := ioutil.ReadFile("testdata.txt")
if err != nil {
// First run, write test data since it doesn't exist
if !os.IsNotExist(err) {
t.Error(err)
}
ioutil.Write("testdata.txt", actual, 0644)
actual = expected
}
if expected != actual {
t.Errorf("Expected %s, got %s", expected, actual)
}
}
Eu recomendo usar a Pretty Printer Library . Em que você pode imprimir qualquer estrutura com muita facilidade.
Instalar Biblioteca
ou
go get github.com/kr/pretty
Agora faça isso no seu código
package main
import (
fmt
github.com/kr/pretty
)
func main(){
type Project struct {
Id int64 `json:"project_id"`
Title string `json:"title"`
Name string `json:"name"`
Data Data `json:"data"`
Commits Commits `json:"commits"`
}
fmt.Printf("%# v", pretty.Formatter(Project)) //It will print all struct details
fmt.Printf("%# v", pretty.Formatter(Project.Id)) //It will print component one by one.
}
Além disso, você pode obter diferença entre os componentes desta biblioteca e muito mais. Você também pode dar uma olhada na biblioteca do Documentos aqui.
pretty.Formatter
Quando você possui estruturas mais complexas, pode ser necessário converter para JSON antes de imprimir:
// Convert structs to JSON.
data, err := json.Marshal(myComplexStruct)
fmt.Printf("%s\n", data)
Visite aqui para ver o código completo. Aqui você também encontrará um link para um terminal on-line onde o código completo pode ser executado e o programa representa como extrair as informações da estrutura (nome do campo, tipo e valor). Abaixo está o trecho de programa que imprime apenas os nomes dos campos.
package main
import "fmt"
import "reflect"
func main() {
type Book struct {
Id int
Name string
Title string
}
book := Book{1, "Let us C", "Enjoy programming with practice"}
e := reflect.ValueOf(&book).Elem()
for i := 0; i < e.NumField(); i++ {
fieldName := e.Type().Field(i).Name
fmt.Printf("%v\n", fieldName)
}
}
/*
Id
Name
Title
*/
Há também go-render , que lida com a recursão do ponteiro e muita classificação de chave para os mapas string e int.
Instalação:
go get github.com/luci/go-render/render
Exemplo:
type customType int
type testStruct struct {
S string
V *map[string]int
I interface{}
}
a := testStruct{
S: "hello",
V: &map[string]int{"foo": 0, "bar": 1},
I: customType(42),
}
fmt.Println("Render test:")
fmt.Printf("fmt.Printf: %#v\n", a)))
fmt.Printf("render.Render: %s\n", Render(a))
Que imprime:
fmt.Printf: render.testStruct{S:"hello", V:(*map[string]int)(0x600dd065), I:42}
render.Render: render.testStruct{S:"hello", V:(*map[string]int){"bar":1, "foo":0}, I:render.customType(42)}
fmt.Printf("%+v\n", project)
Esta é a maneira básica de imprimir os detalhes
Outra maneira é criar uma função chamada toString
que aceite struct, formate os campos como desejar.
import (
"fmt"
)
type T struct {
x, y string
}
func (r T) toString() string {
return "Formate as u need :" + r.x + r.y
}
func main() {
r1 := T{"csa", "ac"}
fmt.Println("toStringed : ", r1.toString())
}
Stringer
interface. Seria algo como isto: func (t T) String() string { return fmt.Sprintf("SomeT{TID: %d, TField: %d, SomeTField: %s, SomeAnotherField: %s}", t.ID, t.Field, t.SomeTField, t.SomeAnotherField) }
Sem usar bibliotecas externas e com nova linha após cada campo:
log.Println(
strings.Replace(
fmt.Sprintf("%#v", post), ", ", "\n", -1))
type Response struct {
UserId int `json:"userId"`
Id int `json:"id"`
Title string `json:"title"`
Body string `json:"body"`
}
func PostsGet() gin.HandlerFunc {
return func(c *gin.Context) {
xs, err := http.Get("https://jsonplaceholder.typicode.com/posts")
if err != nil {
log.Println("The HTTP request failed with error: ", err)
}
data, _ := ioutil.ReadAll(xs`enter code here`.Body)
// this will print the struct in console
fmt.Println(string(data))
// this is to send as response for the API
bytes := []byte(string(data))
var res []Response
json.Unmarshal(bytes, &res)
c.JSON(http.StatusOK, res)
}
}
muito simples eu não tenho a estrutura de dados e confirma então mudei o
package main
import (
"fmt"
)
type Project struct {
Id int64 `json:"project_id"`
Title string `json:"title"`
Name string `json:"name"`
Data string `json:"data"`
Commits string `json:"commits"`
}
func main() {
p := Project{
1,
"First",
"Ankit",
"your data",
"Commit message",
}
fmt.Println(p)
}
Para aprender, você pode obter ajuda aqui: https://gobyexample.com/structs
Talvez isso não deva ser aplicado para solicitações de produção, mas se você estiver no modo de depuração, sugiro que você siga a abordagem abaixo.
marshalledText, _ := json.MarshalIndent(inputStruct, "", " ")
fmt.Println(string(marshalledText))
Isso resulta na formatação dos dados no formato json com maior legibilidade.
A maioria desses pacotes depende do pacote reflect para tornar essas coisas possíveis.
fmt.Sprintf () está usando -> func (p * pp) printArg (interface de argumento {}, runa de verbo) da biblioteca padrão
Vá para a linha 638 -> https://golang.org/src/fmt/print.go
Reflexão:
https://golang.org/pkg/reflect/
Código de exemplo:
https://github.com/donutloop/toolkit/blob/master/debugutil/prettysprint.go
fmt.Println("%+v", structure variable)
Uma maneira melhor de fazer isso seria criar uma constante global para a string "% + v" em um pacote chamado "commons" (talvez) e usá-la em qualquer lugar do código
//In commons package
const STRUCTURE_DATA_FMT = "%+v"
//In your code everywhere
fmt.Println(commons.STRUCTURE_DATA_FMT, structure variable)
Println
função não aceita um argumento de cadeia de formato. Você diz que uma constante global é melhor, mas não justificou por que é melhor que a resposta marcada. Você criou um rótulo não padrão para uma sequência de formato conhecida. O rótulo é muito mais longo, mais difícil de lembrar e ninguém mais que trabalha no seu código o usaria. Ele usa ALL_CAPS e um sublinhado sobre o qual todos os golang-langs se queixam. A convenção é mixedCaps
golang.org/doc/effective_go.html#mixed-caps Provavelmente, é melhor remover esta resposta.
fmt.Println
.