Réponses:
Pour imprimer le nom des champs dans une structure:
fmt.Printf("%+v\n", yourProject)
De l' fmt
emballage :
lors de l'impression de structures, l'indicateur plus (
%+v
) ajoute des noms de champ
Cela suppose que vous ayez une instance de Project (dans ' yourProject
')
L'article JSON et Go donnera plus de détails sur la façon de récupérer les valeurs d'une structure JSON.
Cette page d'exemple Go fournit une autre technique:
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))
Cela imprimerait:
{"page":1,"fruits":["apple","peach","pear"]}
Si vous n'avez aucune instance, vous devez utiliser la réflexion pour afficher le nom du champ d'une structure donnée, comme dans cet exemple .
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())
}
Je veux recommander go-spew , qui selon leur github "implémente une jolie imprimante profonde pour les structures de données Go pour aider au débogage"
go get -u github.com/davecgh/go-spew/spew
exemple d'utilisation:
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)
}
production:
(main.Project) {
Id: (int64) 0,
Title: (string) (len=5) "world",
Name: (string) (len=5) "hello",
Data: (string) "",
Commits: (string) ""
}
mes 2 cents seraient à utiliser json.MarshalIndent
- surpris, ce n'est pas suggéré, car c'est le plus simple. par exemple:
func prettyPrint(i interface{}) string {
s, _ := json.MarshalIndent(i, "", "\t")
return string(s)
}
pas de dépôts externes et donne une sortie bien formatée.
"\t"
par " "
si vous voulez mettre en retrait l'espace à la place
Je pense qu'il serait préférable d'implémenter un limon personnalisé si vous voulez une sorte de sortie formatée d'un struct
par exemple
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)
, me lance main.struct
avec struct type
quelle est la différence entre "%#v"
et "%+v"
@cokebol
Alternativement, essayez d'utiliser cette fonction 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)
}
Pour l'utiliser, vous n'avez pas besoin de packages supplémentaires à l'exception de fmt
et encoding/json
, juste une référence, un pointeur vers ou un littéral de la structure que vous avez créée.
Pour utiliser, prenez simplement votre structure, initialisez-la dans le paquet principal ou dans le paquet dans lequel vous vous trouvez et passez-la 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)
}
Sa sortie serait
### struct as a pointer ###
{
"Network": "10.1.1.0",
"Mask": 24
}
Jouez avec le code ici .
J'aime la litière .
De leur readme:
type Person struct {
Name string
Age int
Parent *Person
}
litter.Dump(Person{
Name: "Bob",
Age: 20,
Parent: &Person{
Name: "Jane",
Age: 50,
},
})
Sdump
est assez pratique dans les tests:
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)
}
}
Je recommande d'utiliser Pretty Printer Library . En cela, vous pouvez imprimer n'importe quelle structure très facilement.
Installer la bibliothèque
ou
go get github.com/kr/pretty
Maintenant, fais comme ça dans ton code
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.
}
Vous pouvez également obtenir la différence entre les composants via cette bibliothèque et bien plus encore. Vous pouvez également consulter les documents de la bibliothèque ici.
pretty.Formatter
Lorsque vous avez des structures plus complexes, vous devrez peut-être convertir en JSON avant d'imprimer:
// Convert structs to JSON.
data, err := json.Marshal(myComplexStruct)
fmt.Printf("%s\n", data)
Visitez ici pour voir le code complet. Ici, vous trouverez également un lien vers un terminal en ligne où le code complet peut être exécuté et le programme représente comment extraire les informations de la structure (nom du champ leur type et valeur). Ci-dessous, l'extrait de programme qui imprime uniquement les noms de champ.
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
*/
Il y a aussi go-render , qui gère la récursivité du pointeur et beaucoup de tri de clé pour les cartes de chaîne et int.
Installation:
go get github.com/luci/go-render/render
Exemple:
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))
Qui 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)
Il s'agit de la méthode de base pour imprimer les détails
Une autre façon est de créer un func appelé toString
qui prend struct, formatez les champs comme vous le souhaitez.
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. Cela ressemblerait à ceci: 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) }
Sans utiliser de bibliothèques externes et avec une nouvelle ligne après chaque champ:
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)
}
}
très simple, je n'ai pas la structure des données et des validations J'ai donc changé la
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)
}
Pour apprendre, vous pouvez obtenir de l'aide à partir d'ici: https://gobyexample.com/structs
Peut-être que cela ne devrait pas être appliqué pour les demandes de production, mais si vous êtes en mode débogage, je vous suggère de suivre l'approche ci-dessous.
marshalledText, _ := json.MarshalIndent(inputStruct, "", " ")
fmt.Println(string(marshalledText))
Il en résulte un formatage des données au format json avec une lisibilité accrue.
La plupart de ces packages s'appuient sur le package Reflect pour rendre ces choses possibles.
fmt.Sprintf () utilise -> func (p * pp) printArg (interface arg {}, verbe rune) de la lib standard
Allez à la ligne 638 -> https://golang.org/src/fmt/print.go
Réflexion:
https://golang.org/pkg/reflect/
Exemple de code:
https://github.com/donutloop/toolkit/blob/master/debugutil/prettysprint.go
fmt.Println("%+v", structure variable)
Une meilleure façon de procéder serait de créer une constante globale pour la chaîne "% + v" dans un package appelé "commons" (peut-être) et de l'utiliser partout dans votre code
//In commons package
const STRUCTURE_DATA_FMT = "%+v"
//In your code everywhere
fmt.Println(commons.STRUCTURE_DATA_FMT, structure variable)
Println
fonction n'accepte pas un argument de chaîne de format. Vous dites qu'une constante globale est meilleure mais n'avez pas justifié pourquoi elle est meilleure que la réponse marquée. Vous avez créé une étiquette non standard pour une chaîne de format bien connue. L'étiquette est beaucoup plus longue, plus difficile à retenir et personne d'autre qui travaille sur votre code ne l'utilisera. Il utilise à la fois ALL_CAPS et un trait de soulignement dont tout linter golang se plaindra. La convention est mixedCaps
golang.org/doc/effective_go.html#mixed-caps Il vaut probablement mieux supprimer cette réponse.
fmt.Println
.