Odpowiedzi:
Aby wydrukować nazwę pól w strukturze:
fmt.Printf("%+v\n", yourProject)
Z fmt
paczki :
podczas drukowania struktur, flaga plus (
%+v
) dodaje nazwy pól
To znaczy, że masz instancję projektu (w „ yourProject
”)
Artykuł JSON i Go poda więcej szczegółów na temat pobierania wartości ze struktury JSON.
Ta strona z przykładami zawiera inną 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))
To by wydrukowało:
{"page":1,"fruits":["apple","peach","pear"]}
Jeśli nie masz żadnej instancji, musisz użyć refleksji, aby wyświetlić nazwę pola danej struktury, jak w tym przykładzie .
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())
}
Chcę polecić go-spew , który zgodnie z ich githubem „Implementuje bardzo ładną drukarkę dla struktur danych Go, aby pomóc w debugowaniu”
go get -u github.com/davecgh/go-spew/spew
przykład użycia:
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)
}
wynik:
(main.Project) {
Id: (int64) 0,
Title: (string) (len=5) "world",
Name: (string) (len=5) "hello",
Data: (string) "",
Commits: (string) ""
}
moje 2 centy byłyby użyteczne json.MarshalIndent
- zdziwione, że nie jest to sugerowane, ponieważ jest najprostsze. na przykład:
func prettyPrint(i interface{}) string {
s, _ := json.MarshalIndent(i, "", "\t")
return string(s)
}
brak zewnętrznych dep i skutkuje ładnie sformatowanym wyjściem.
"\t"
ze " "
jeśli chcesz przestrzeń wcięcia zamiast
Myślę, że lepiej byłoby zaimplementować niestandardowy stringer, jeśli chcesz jakiegoś sformatowanego wyjścia struct
na przykład
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)
, Wyrzuca mnie main.struct
z struct type
tego, co jest różnica między "%#v"
i "%+v"
@cokebol
Alternatywnie spróbuj użyć tej funkcji 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)
}
Aby tego użyć, nie potrzebujesz żadnych dodatkowych pakietów, z wyjątkiem fmt
i encoding/json
, tylko odniesienie, wskaźnik do lub dosłownie utworzonej struktury.
Aby użyć, po prostu weź swoją strukturę, zainicjuj ją w pakiecie głównym lub w dowolnym pakiecie, w którym się znajdujesz, i przekaż ją 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)
}
Jego wyjście byłoby
### struct as a pointer ###
{
"Network": "10.1.1.0",
"Mask": 24
}
Pobaw się z kodu tutaj .
Lubię śmieci .
Z ich pliku Readme:
type Person struct {
Name string
Age int
Parent *Person
}
litter.Dump(Person{
Name: "Bob",
Age: 20,
Parent: &Person{
Name: "Jane",
Age: 50,
},
})
Sdump
jest bardzo przydatny w testach:
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)
}
}
Polecam korzystać z Pretty Printer Library . Dzięki temu możesz bardzo łatwo wydrukować dowolną strukturę.
Zainstaluj bibliotekę
lub
go get github.com/kr/pretty
Teraz zrób tak w swoim kodzie
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.
}
Ponadto można uzyskać różnicę między składnikiem za pośrednictwem tej biblioteki i tak dalej. Możesz także zajrzeć do biblioteki dokumentów tutaj.
pretty.Formatter
Jeśli masz bardziej złożone struktury, przed drukowaniem może być konieczna konwersja do JSON:
// Convert structs to JSON.
data, err := json.Marshal(myComplexStruct)
fmt.Printf("%s\n", data)
Odwiedź tutaj, aby zobaczyć pełny kod. Tutaj znajdziesz również łącze do terminala online, w którym można uruchomić cały kod, a program reprezentuje sposób wydobywania informacji o strukturze (nazwa pola, ich typ i wartość). Poniżej znajduje się fragment programu, który drukuje tylko nazwy pól.
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
*/
Istnieje również go-render , który obsługuje rekurencję wskaźnika i wiele sortowania kluczy dla map ciągów i map int.
Instalacja:
go get github.com/luci/go-render/render
Przykład:
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))
Które wydruki:
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)
Jest to podstawowy sposób drukowania szczegółów
Innym sposobem jest utworzenie func o nazwie toString
strukturalnej, sformatowanie pól według własnego uznania.
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
interfejs. Wyglądałoby to tak: 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) }
Bez użycia zewnętrznych bibliotek i nowej linii po każdym polu:
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)
}
}
bardzo proste Nie mam struktury danych i zatwierdzeń, więc zmieniłem
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)
}
Aby się uczyć, możesz uzyskać pomoc tutaj: https://gobyexample.com/structs
Być może nie należy tego stosować w przypadku zleceń produkcyjnych, ale jeśli jesteś w trybie debugowania, sugeruję zastosować poniższe podejście.
marshalledText, _ := json.MarshalIndent(inputStruct, "", " ")
fmt.Println(string(marshalledText))
Powoduje to formatowanie danych w formacie json o zwiększonej czytelności.
Większość z tych pakietów polega na pakiecie odzwierciedlającym, aby umożliwić takie rzeczy.
fmt.Sprintf () używa -> func (p * pp) printArg (interfejs arg {}, runa czasownika) standardowej biblioteki lib
Idź do linii 638 -> https://golang.org/src/fmt/print.go
Odbicie:
https://golang.org/pkg/reflect/
Przykładowy kod:
https://github.com/donutloop/toolkit/blob/master/debugutil/prettysprint.go
fmt.Println("%+v", structure variable)
Lepszym sposobem na to byłoby utworzenie globalnej stałej dla ciągu „% + v” w pakiecie o nazwie „commons” (być może) i użycie go wszędzie w kodzie
//In commons package
const STRUCTURE_DATA_FMT = "%+v"
//In your code everywhere
fmt.Println(commons.STRUCTURE_DATA_FMT, structure variable)
Println
funkcja nie akceptuje argumentu formatu ciągu. Mówisz, że stała globalna jest lepsza, ale nie uzasadniłeś, dlaczego jest lepsza niż zaznaczona odpowiedź. Utworzono niestandardową etykietę dla dobrze znanego ciągu formatu. Etykieta jest znacznie dłuższa, trudniejsza do zapamiętania i nikt inny, kto pracuje nad twoim kodem, by jej nie użył. Używa zarówno ALL_CAPS, jak i podkreślenia, na które narzeka każdy golang. Konwencja to mixedCaps
golang.org/doc/effective_go.html#mixed-caps Prawdopodobnie najlepiej usunąć tę odpowiedź.
fmt.Println
.