Как печатать структурные переменные в консоли?
Как я могу напечатать (в консоли) Id
, Title
, Name
и т.д. этой структуры в Голанге?
type Project struct {
Id int64 `json:"project_id"`
Title string `json:"title"`
Name string `json:"name"`
Data Data `json:"data"`
Commits Commits `json:"commits"`
}
Ответы
Ответ 1
Чтобы напечатать название полей в структуре:
fmt.Printf("%+v\n", yourProject)
Из пакета fmt
:
при печати структур флаг "плюс" (%+v
) добавляет имена полей
Предполагается, что у вас есть экземпляр Project (в yourProject
)
В статье JSON and Go будет дано больше подробностей о том, как извлечь значения из структуры JSON.
Эта страница Go by 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())
}
Ответ 2
Я хочу рекомендовать 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) ""
}
Ответ 3
мой 2cents должен был бы использовать json.MarshalIndent
- удивленный, это не предложено, поскольку это является самым прямым. например:
func prettyPrint(i interface{}) string {
s, _ := json.MarshalIndent(i, "", "\t")
return string(s)
}
нет внешних депов и приводит к красиво отформатированному выводу.
Ответ 4
Я думаю, что было бы лучше реализовать пользовательский стрингер, если вы хотите получить отформатированный вывод 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)
}
Ответ 5
p = Project{...}
fmt.Printf("%+v", p)
fmt.Printf("%#v", p) //with type
Ответ 6
Посетите здесь, чтобы увидеть полный код. Здесь вы также найдете ссылку для онлайн-терминала, где полный код может быть запущен, а программа представляет, как извлечь информацию о структуре (имя поля их тип и значение). Ниже приведен фрагмент программы, который печатает только имена полей.
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
*/
Ответ 7
Я люблю мусор.
Из их readme:
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)
}
}
Ответ 8
Если у вас есть более сложные структуры, вам может потребоваться преобразовать в JSON перед печатью:
// Convert structs to JSON.
data, err := json.Marshal(myComplexStruct)
fmt.Printf("%s\n", data)
Источник: https://gist.github.com/tetsuok/4942960
Ответ 9
Я рекомендую использовать Pretty Printer Library. В этом вы можете распечатать любую структуру очень легко.
-
Установить библиотеку
https://github.com/kr/pretty
или же
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.
}
Также вы можете получить разницу между компонентами через эту библиотеку и многое другое. Вы также можете посмотреть библиотечные документы здесь.
Ответ 10
Или попробуйте использовать эту функцию 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()
пакете, который вы используете, и передайте его в 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
}
Поиграйте с кодом здесь.
Ответ 11
Здесь также 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)}
Ответ 12
Другой способ: создать func с именем 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())
}
Ответ 13
Я хочу порекомендовать Stuct Example GO языковая программа с примером типа Struc.
package main
import (
"fmt"
)
func main() {
type Salary struct{
Basic, HRA, TA float64
}
type Employee struct{
FirstName, LastName, Email string
Age int
MonthlySalary []Salary
}
e := Employee{
FirstName: "Mark",
LastName: "Jones",
Email: "[email protected]",
Age: 25,
MonthlySalary: []Salary{
Salary{
Basic:15000.00,
HRA:5000.00,
TA:2000.00,
},
Salary{
Basic:16000.00,
HRA:5000.00,
TA:2100.00,
},
Salary{
Basic:17000.00,
HRA:5000.00,
TA:2200.00,
},
},
}
fmt.Println(e.FirstName,e.LastName)
fmt.Println(e.Age)
fmt.Println(e.Email)
fmt.Println(e.MonthlySalary[0])
fmt.Println(e.MonthlySalary[1])
fmt.Println(e.MonthlySalary[2])
}
Ответ 14
Без использования внешних библиотек и новой строки после каждого поля:
log.Println(
strings.Replace(
fmt.Sprintf("%#v", post), ", ", "\n", -1))
Ответ 15
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)