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ừ fmtgó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/spewví 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 typefmt.Printf(%#v, p), Ném cho tôi main.structvớ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ừ fmtvà 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/prettyBâ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/renderThí 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à toStringstruct, đị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())
}Stringergiao 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)Printlnhà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.