Відповіді:
Щоб надрукувати назву полів у структурі:
fmt.Printf("%+v\n", yourProject)
З fmt
пакета :
при структурах друку прапор плюс (
%+v
) додає назви полів
Це передбачає, що у вас є екземпляр Project (в ' yourProject
')
У статті JSON і Go буде детальніше про те, як отримати значення зі структури JSON.
На цій сторінці Go for example надається інша методика:
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))
Це буде друкувати:
{"page":1,"fruits":["apple","peach","pear"]}
Якщо у вас немає жодного примірника, тоді вам потрібно використовувати відображення для відображення назви поля заданої структури, як у цьому прикладі .
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())
}
Я хочу порекомендувати go-spew , який згідно з їхнім github "Реалізує глибокий симпатичний принтер для структур даних Go для допомоги в налагодженні"
go get -u github.com/davecgh/go-spew/spew
приклад використання:
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)
}
вихід:
(main.Project) {
Id: (int64) 0,
Title: (string) (len=5) "world",
Name: (string) (len=5) "hello",
Data: (string) "",
Commits: (string) ""
}
мої 2 центи були б використані json.MarshalIndent
- здивовано, що це не пропонується, оскільки це найпростіше. наприклад:
func prettyPrint(i interface{}) string {
s, _ := json.MarshalIndent(i, "", "\t")
return string(s)
}
відсутність зовнішніх деп, що призводить до гарного форматування виводу.
"\t"
з , " "
якщо ви хочете простір відступів замість
Я думаю, було б краще реалізувати користувацький стрингер, якщо ви хочете якийсь форматизований вихід з struct
наприклад
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)
, кидає мене, main.struct
в struct type
чому різниця між "%#v"
і "%+v"
@cokebol
Крім того, спробуйте скористатися цією функцією 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)
}
Для використання цього вам не потрібні додаткові пакети за винятком, fmt
а encoding/json
лише посилання, вказівник на або буквальну структуру, яку ви створили.
Для використання просто візьміть структуру, ініціалізуйте її в основному або будь-якому іншому пакеті і передайте його 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)
}
Це буде висновок
### struct as a pointer ###
{
"Network": "10.1.1.0",
"Mask": 24
}
Пограйте з кодом тут .
Мені подобається послід .
З їх прочитаного:
type Person struct {
Name string
Age int
Parent *Person
}
litter.Dump(Person{
Name: "Bob",
Age: 20,
Parent: &Person{
Name: "Jane",
Age: 50,
},
})
Sdump
досить корисний у тестах:
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)
}
}
Я рекомендую використовувати бібліотеку Pretty Printer . Завдяки цьому ви можете легко надрукувати будь-яку структуру.
Встановити бібліотеку
або
go get github.com/kr/pretty
Тепер зробіть так у своєму коді
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.
}
Також ви можете отримати різницю між компонентами через цю бібліотеку тощо. Ви також можете ознайомитись із бібліотечними документами тут.
pretty.Formatter
Якщо у вас складніші структури, вам може знадобитися перетворитись на JSON перед друком:
// Convert structs to JSON.
data, err := json.Marshal(myComplexStruct)
fmt.Printf("%s\n", data)
Завітайте сюди, щоб побачити повний код. Тут ви також знайдете посилання на інтернет-термінал, де можна запустити повний код, і програма представляє, як витягти інформацію структури (назва поля, їх тип та значення). Нижче представлений фрагмент програми, який друкує лише імена полів.
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
*/
Є також go-render , який обробляє рекурсію вказівника та безліч сортування ключів для рядків та int карт.
Установка:
go get github.com/luci/go-render/render
Приклад:
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))
Які відбитки:
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)
Це основний спосіб друку деталей
Інший спосіб - створити функцію під назвою, toString
яка бере структуру, форматуйте поля за вашим бажанням.
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
інтерфейс. Це виглядало б приблизно так: 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) }
Без використання зовнішніх бібліотек та з новим рядком після кожного поля:
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)
}
}
дуже просто, у мене немає структури даних і комітетів, тому я змінив
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)
}
Для навчання ви можете скористатися допомогою тут: https://gobyexample.com/structs
Можливо, це не слід застосовувати для виробничих запитів, але якщо ви перебуваєте в режимі налагодження, я пропоную вам дотримуватися наступного підходу.
marshalledText, _ := json.MarshalIndent(inputStruct, "", " ")
fmt.Println(string(marshalledText))
Це призводить до форматування даних у форматі json із збільшенням читабельності.
Більшість цих пакетів покладаються на пакет відображення, щоб зробити такі речі можливими.
fmt.Sprintf () використовує -> func (p * pp) printArg (arg інтерфейс {}, дієслова rune) стандартної lib
Перейдіть до рядка 638 -> https://golang.org/src/fmt/print.go
Відображення:
https://golang.org/pkg/reflect/
Приклад коду:
https://github.com/donutloop/toolkit/blob/master/debugutil/prettysprint.go
fmt.Println("%+v", structure variable)
Кращим способом зробити це було б створити глобальну константу для рядка "% + v" в пакеті під назвою "commons" (можливо) і використовувати його скрізь у своєму коді
//In commons package
const STRUCTURE_DATA_FMT = "%+v"
//In your code everywhere
fmt.Println(commons.STRUCTURE_DATA_FMT, structure variable)
Println
функція не приймає аргумент рядкового формату. Ви кажете, що глобальна константа є кращою, але ви не виправдали, чому це краще, ніж позначена відповідь. Ви створили нестандартну мітку для добре відомого рядка формату. Мітка набагато довша, її складніше запам’ятати, і ніхто більше, хто працює над вашим кодом, не використовував би її. Він використовує як ALL_CAPS, так і підкреслення, на яке скаржиться кожен голанг-підводка. Конвенція є mixedCaps
golang.org/doc/effective_go.html#mixed-caps Мабуть, найкраще видалити цю відповідь.
fmt.Println
.