Comment puis-je imprimer (dans la console) les Id
, Title
, Name
, etc. de cette structure dans Golang?
type Project struct {
Id int64 `json:"project_id"`
Title string `json:"title"`
Name string `json:"name"`
Data Data `json:"data"`
Commits Commits `json:"commits"`
}
Pour imprimer le nom des champs dans une structure:
fmt.Printf("%+v\n", yourProject)
À partir du paquet fmt
:
lors de l'impression de structures, l'indicateur plus (
%+v
) ajoute les noms de champs
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 Aller par exemple 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 pas d'instance, alors vous devez utiliser reflexion 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 afin de faciliter le 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)
}
sortie:
(main.Project) {
Id: (int64) 0,
Title: (string) (len=5) "world",
Name: (string) (len=5) "hello",
Data: (string) "",
Commits: (string) ""
}
mes 2cents serait d'utiliser json.MarshalIndent
- surpris que cela ne soit 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 résultats dans une sortie bien formatée.
Je pense qu'il serait préférable d'implémenter un stringer personnalisé si vous voulez une sorte de sortie formatée d'une 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
Visitez ici pour voir le code complet. Vous trouverez également ici un lien vers un terminal en ligne où le code complet peut être exécuté et le programme explique comment extraire les informations de la structure (nom du champ, type et valeur). Ci-dessous l'extrait de programme qui n'imprime que les noms de champs.
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
*/
J'aime 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 très 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)
}
}
Sinon, 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 utiliser cela, vous n'avez besoin d'aucun paquet supplémentaire, à l'exception de fmt
et encoding/json
, mais simplement d'une référence, d'un pointeur vers ou d'un littéral de la structure que vous avez créée.
Pour utiliser simplement votre structure, initialisez-la dans le paquet principal ou quel que soit votre package et passez-la dans 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 .
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 aussi faire la différence entre composant via cette bibliothèque et bien plus encore. Vous pouvez également consulter la bibliothèque Docs ici.
Il y a aussi go-render , qui gère la récursion de pointeurs et beaucoup de tri de clés pour les cartes string 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))
Quelles impressions:
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)}
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))
Vous pouvez également créer une fonction appelée toString
qui prend en charge la structure, formatez les champs À votre guise.
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())
}
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)