Câu trả lời:
Để in tên của các trường trong một cấu trúc:
fmt.Printf("%+v\n", yourProject)
Từ fmt
gói :
khi in cấu trúc, cờ cộng (
%+v
) thêm tên trường
Điều đó cho rằng bạn có một thể hiện của Dự án (trong ' yourProject
')
Bài viết JSON và Go sẽ cung cấp thêm chi tiết về cách truy xuất các giá trị từ cấu trúc JSON.
Đây Go bởi trang ví dụ cung cấp kỹ thuật khác:
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))
Điều đó sẽ in:
{"page":1,"fruits":["apple","peach","pear"]}
Nếu bạn không có bất kỳ trường hợp nào, thì bạn cần sử dụng sự phản chiếu để hiển thị tên của trường của một cấu trúc nhất định, như trong ví dụ này .
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())
}
Tôi muốn giới thiệu go-spew , theo github của họ "Triển khai một máy in đẹp sâu cho cấu trúc dữ liệu Go để hỗ trợ gỡ lỗi"
go get -u github.com/davecgh/go-spew/spew
ví dụ sử dụng:
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)
}
đầu ra:
(main.Project) {
Id: (int64) 0,
Title: (string) (len=5) "world",
Name: (string) (len=5) "hello",
Data: (string) "",
Commits: (string) ""
}
2cents của tôi sẽ được sử dụng json.MarshalIndent
- thật ngạc nhiên khi điều này không được đề xuất, vì nó đơn giản nhất. ví dụ:
func prettyPrint(i interface{}) string {
s, _ := json.MarshalIndent(i, "", "\t")
return string(s)
}
không có deps bên ngoài và kết quả trong đầu ra được định dạng độc đáo.
"\t"
bằng " "
nếu bạn muốn thụt lề thay thế
Tôi nghĩ sẽ tốt hơn nếu thực hiện một stringer tùy chỉnh nếu bạn muốn một số loại đầu ra được định dạng của một struct
ví dụ
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)
, Ném cho tôi main.struct
với struct type
sự khác biệt giữa là những gì "%#v"
và "%+v"
@cokebol
Ngoài ra, hãy thử sử dụng chức năng này 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)
}
Để sử dụng điều này, bạn không cần bất kỳ gói bổ sung nào ngoại trừ fmt
và encoding/json
, chỉ cần một tham chiếu, con trỏ tới hoặc bằng chữ của cấu trúc bạn đã tạo.
Để sử dụng, chỉ cần lấy cấu trúc của bạn, khởi tạo nó trong gói chính hoặc bất kỳ gói nào bạn đang sử dụng và chuyển nó vào 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)
}
Đầu ra của nó sẽ là
### struct as a pointer ###
{
"Network": "10.1.1.0",
"Mask": 24
}
Chơi xung quanh với mã ở đây .
Tôi thích xả rác .
Từ readme của họ:
type Person struct {
Name string
Age int
Parent *Person
}
litter.Dump(Person{
Name: "Bob",
Age: 20,
Parent: &Person{
Name: "Jane",
Age: 50,
},
})
Sdump
là khá tiện dụng trong các bài kiểm tra:
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)
}
}
Tôi khuyên bạn nên sử dụng Thư viện máy in đẹp . Trong đó bạn có thể in bất kỳ cấu trúc rất dễ dàng.
Cài đặt thư viện
hoặc là
go get github.com/kr/pretty
Bây giờ làm như thế này trong mã của bạn
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.
}
Ngoài ra, bạn có thể nhận được sự khác biệt giữa các thành phần thông qua thư viện này và nhiều hơn nữa. Bạn cũng có thể xem thư viện Docs tại đây.
pretty.Formatter
Khi bạn có các cấu trúc phức tạp hơn, bạn có thể cần phải chuyển đổi sang JSON trước khi in:
// Convert structs to JSON.
data, err := json.Marshal(myComplexStruct)
fmt.Printf("%s\n", data)
Chuyến thăm vào đây để xem mã hoàn chỉnh. Tại đây, bạn cũng sẽ tìm thấy một liên kết cho một thiết bị đầu cuối trực tuyến nơi có thể chạy mã hoàn chỉnh và chương trình trình bày cách trích xuất thông tin của cấu trúc (tên trường loại & giá trị của chúng). Dưới đây là đoạn chương trình chỉ in tên trường.
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
*/
Ngoài ra còn có kết xuất , xử lý đệ quy con trỏ và rất nhiều cách sắp xếp khóa cho bản đồ chuỗi và int.
Cài đặt:
go get github.com/luci/go-render/render
Thí dụ:
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))
Bản in nào:
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)
Đây là cách cơ bản để in các chi tiết
Một cách khác là, tạo một func được gọi là toString
struct, định dạng các trường theo ý muốn.
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
giao diện. Nó sẽ trông giống như thế này: 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) }
Không sử dụng các thư viện bên ngoài và với dòng mới sau mỗi trường:
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)
}
}
rất đơn giản Tôi không có cấu trúc của Dữ liệu và Cam kết Vì vậy tôi đã thay đổi
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)
}
Để học, bạn có thể nhận trợ giúp từ đây: https://gobyexample.com/structs
Có thể điều này không nên được áp dụng cho các yêu cầu sản xuất nhưng nếu bạn đang ở chế độ gỡ lỗi, tôi khuyên bạn nên làm theo cách tiếp cận dưới đây.
marshalledText, _ := json.MarshalIndent(inputStruct, "", " ")
fmt.Println(string(marshalledText))
Điều này dẫn đến việc định dạng dữ liệu ở định dạng json với khả năng đọc dễ dàng hơn.
Hầu hết các gói này đều dựa vào gói phản ánh để biến những thứ đó thành có thể.
fmt.Sprintf () đang sử dụng -> func (p * pp) printArg (giao diện arg {}, động từ rune) của lib chuẩn
Chuyển đến dòng 638 -> https://golang.org/src/fmt/print.go
Suy ngẫm:
https://golang.org/pkg/reflect/
Mã ví dụ:
https://github.com/donutloop/toolkit/blob/master/debugutil/prettysprint.go
fmt.Println("%+v", structure variable)
Cách tốt hơn để làm điều này là tạo một hằng số toàn cầu cho chuỗi "% + v" trong gói có tên là "commons" (có thể) và sử dụng nó ở mọi nơi trong mã của bạn
//In commons package
const STRUCTURE_DATA_FMT = "%+v"
//In your code everywhere
fmt.Println(commons.STRUCTURE_DATA_FMT, structure variable)
Println
hàm không chấp nhận đối số chuỗi định dạng. Bạn nói rằng một hằng số toàn cầu là tốt hơn nhưng không thể biện minh được tại sao nó tốt hơn câu trả lời được đánh dấu. Bạn đã tạo nhãn không chuẩn cho chuỗi định dạng nổi tiếng. Nhãn dài hơn, khó nhớ hơn và không ai khác làm việc với mã của bạn sẽ sử dụng nó. Nó sử dụng cả ALL_CAPS và dấu gạch dưới mà mọi kẻ nói dối golang sẽ phàn nàn. Quy ước là mixedCaps
golang.org/doc/effective_go.html#mixed-caps Có lẽ tốt nhất để xóa câu trả lời này.
fmt.Println
.