Antworten:
So drucken Sie den Namen der Felder in einer Struktur:
fmt.Printf("%+v\n", yourProject)
Aus dem fmt
Paket :
Beim Drucken von Strukturen
%+v
fügt das Plus-Flag ( ) Feldnamen hinzu
Angenommen, Sie haben eine Instanz von Project (in ' yourProject
').
Der Artikel JSON und Go enthält weitere Informationen zum Abrufen der Werte aus einer JSON-Struktur.
Diese Beispielseite bietet eine andere Technik:
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))
Das würde drucken:
{"page":1,"fruits":["apple","peach","pear"]}
Wenn Sie keine Instanz haben, müssen Sie Reflection verwenden , um den Namen des Felds einer bestimmten Struktur anzuzeigen, wie in diesem Beispiel .
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())
}
Ich möchte go-spew empfehlen , das laut Github "einen sehr hübschen Drucker für Go-Datenstrukturen implementiert , um das Debuggen zu erleichtern".
go get -u github.com/davecgh/go-spew/spew
Anwendungsbeispiel:
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)
}
Ausgabe:
(main.Project) {
Id: (int64) 0,
Title: (string) (len=5) "world",
Name: (string) (len=5) "hello",
Data: (string) "",
Commits: (string) ""
}
Meine 2 Cent wären zu verwenden json.MarshalIndent
- überrascht, dass dies nicht empfohlen wird, da es am einfachsten ist. zum Beispiel:
func prettyPrint(i interface{}) string {
s, _ := json.MarshalIndent(i, "", "\t")
return string(s)
}
Keine externen Deps und führt zu einer gut formatierten Ausgabe.
"\t"
mit , " "
wenn Sie Platz Einrücken wollen statt
Ich denke, es wäre besser, einen benutzerdefinierten Stringer zu implementieren, wenn Sie eine formatierte Ausgabe von a wünschen struct
zum Beispiel
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)
, wirft mich main.struct
mit struct type
was ist der Unterschied zwischen "%#v"
und "%+v"
@cokebol
Alternativ können Sie diese Funktion verwenden 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)
}
Um dies zu verwenden, benötigen Sie keine zusätzlichen Pakete mit Ausnahme von fmt
und encoding/json
lediglich einer Referenz, einem Zeiger oder einem Literal der von Ihnen erstellten Struktur.
Um es zu verwenden, nehmen Sie einfach Ihre Struktur, initialisieren Sie sie in main oder einem anderen Paket, in dem Sie sich befinden, und übergeben Sie sie 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)
}
Die Ausgabe wäre
### struct as a pointer ###
{
"Network": "10.1.1.0",
"Mask": 24
}
Spielen Sie mit dem Code um hier .
Ich mag Müll .
Aus ihrer Readme:
type Person struct {
Name string
Age int
Parent *Person
}
litter.Dump(Person{
Name: "Bob",
Age: 20,
Parent: &Person{
Name: "Jane",
Age: 50,
},
})
Sdump
ist ziemlich praktisch in 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)
}
}
Ich empfehle die Verwendung der Pretty Printer Library . Dadurch können Sie jede Struktur sehr einfach drucken.
Bibliothek installieren
oder
go get github.com/kr/pretty
Tun Sie dies jetzt in Ihrem 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.
}
Durch diese Bibliothek und mehr können Sie auch Unterschiede zwischen Komponenten feststellen. Sie können auch einen Blick auf Bibliothek Docs hier.
pretty.Formatter
Wenn Sie komplexere Strukturen haben, müssen Sie möglicherweise vor dem Drucken in JSON konvertieren:
// Convert structs to JSON.
data, err := json.Marshal(myComplexStruct)
fmt.Printf("%s\n", data)
Besuchen Sie hier , um den vollständigen Code zu sehen. Hier finden Sie auch einen Link für ein Online-Terminal, über das der vollständige Code ausgeführt werden kann und das Programm darstellt, wie die Informationen der Struktur extrahiert werden (Feldname, Typ und Wert). Unten finden Sie das Programm-Snippet, das nur die Feldnamen druckt.
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
*/
Es gibt auch Go-Rendering , das die Zeigerrekursion und viele Schlüsselsortierungen für String- und Int-Maps übernimmt.
Installation:
go get github.com/luci/go-render/render
Beispiel:
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))
Welche Drucke:
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)
Dies ist die grundlegende Methode zum Drucken der Details
Eine andere Möglichkeit besteht darin, eine Funktion mit dem Namen toString
struct zu erstellen und die Felder nach Ihren Wünschen zu formatieren.
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
Schnittstelle implementieren . Es würde 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) }
Ohne Verwendung externer Bibliotheken und mit neuer Zeile nach jedem Feld:
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)
}
}
sehr einfach Ich habe nicht die Struktur von Daten und Commits Also habe ich die geändert
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)
}
Informationen zum Lernen erhalten Sie hier: https://gobyexample.com/structs
Möglicherweise sollte dies nicht für Produktionsanforderungen angewendet werden, aber wenn Sie sich im Debugging-Modus befinden, empfehlen wir Ihnen, den folgenden Ansatz zu befolgen.
marshalledText, _ := json.MarshalIndent(inputStruct, "", " ")
fmt.Println(string(marshalledText))
Dies führt zu einer Formatierung der Daten im JSON-Format mit verbesserter Lesbarkeit.
Die meisten dieser Pakete verlassen sich auf das Reflect-Paket, um solche Dinge zu ermöglichen.
fmt.Sprintf () verwendet -> func (p * pp) printArg (arg interface {}, Verbrune) der Standardbibliothek
Gehen Sie zu Zeile 638 -> https://golang.org/src/fmt/print.go
Betrachtung:
https://golang.org/pkg/reflect/
Beispielcode:
https://github.com/donutloop/toolkit/blob/master/debugutil/prettysprint.go
fmt.Println("%+v", structure variable)
Ein besserer Weg, dies zu tun, wäre, eine globale Konstante für die Zeichenfolge "% + v" in einem Paket namens "commons" (möglicherweise) zu erstellen und sie überall in Ihrem Code zu verwenden
//In commons package
const STRUCTURE_DATA_FMT = "%+v"
//In your code everywhere
fmt.Println(commons.STRUCTURE_DATA_FMT, structure variable)
Println
Funktion kein Format-String-Argument akzeptiert. Sie sagen, eine globale Konstante ist besser, haben aber nicht gerechtfertigt, warum sie besser ist als die markierte Antwort. Sie haben eine nicht standardmäßige Beschriftung für eine bekannte Formatzeichenfolge erstellt. Das Etikett ist viel länger, schwerer zu merken und niemand anderes, der an Ihrem Code arbeitet, würde es verwenden. Es verwendet sowohl ALL_CAPS als auch einen Unterstrich, über den sich jeder Golang-Linter beschweren wird. Die Konvention lautet mixedCaps
golang.org/doc/effective_go.html#mixed-caps. Am besten entfernen Sie diese Antwort.
fmt.Println
.