Yanıtlar:
Bir yapıdaki alanların adını yazdırmak için:
fmt.Printf("%+v\n", yourProject)
Gönderen fmt
paketin :
yapılar yazdırılırken, artı bayrağı (
%+v
) alan adları ekler
Bu, bir Proje örneğiniz olduğunu varsayar (' yourProject
' içinde)
JSON ve Go makalesi , değerlerin bir JSON yapısından nasıl alınacağı hakkında daha fazla ayrıntı verecektir.
Bu Örnekle Git sayfası başka bir teknik sağlar:
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))
Bu yazdırır:
{"page":1,"fruits":["apple","peach","pear"]}
Herhangi bir örneğiniz yoksa , bu örnekte olduğu gibi, belirli bir yapıdaki alanın adını görüntülemek için yansıma kullanmanız gerekir .
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())
}
Github'a göre "Go veri yapılarının hata ayıklamaya yardımcı olması için derin ve güzel bir yazıcı uygular" adlı go-spew'i tavsiye etmek istiyorum.
go get -u github.com/davecgh/go-spew/spew
kullanım örneği:
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)
}
çıktı:
(main.Project) {
Id: (int64) 0,
Title: (string) (len=5) "world",
Name: (string) (len=5) "hello",
Data: (string) "",
Commits: (string) ""
}
benim 2 sent kullanmak olacaktır json.MarshalIndent
- en basit olduğu için bu önerilmiyor şaşırttı. Örneğin:
func prettyPrint(i interface{}) string {
s, _ := json.MarshalIndent(i, "", "\t")
return string(s)
}
harici deps yok ve güzel biçimlendirilmiş çıktı ile sonuçlanır.
"\t"
ile " "
Bunun yerine ara girintilemeyi istiyorsanız
Ben biçimlendirilmiş bir çıktı bir tür istiyorsanız özel bir stringer uygulamak daha iyi olacağını düşünüyorum struct
Örneğin
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)
Bana atar main.struct
ile struct type
arasındaki farkın ne "%#v"
ve "%+v"
@cokebol
Alternatif olarak, bu işlevi kullanmayı deneyin 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)
}
Bunu kullanabilmek için, oluşturduğunuz yapı dışında fmt
ve encoding/json
sadece referans, işaretçi veya hazır bilgi haricinde herhangi bir ek pakete ihtiyacınız yoktur .
Kullanmak için sadece yapınızı alın, ana olarak veya içinde bulunduğunuz herhangi bir paketi başlatın ve içine geçirin 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)
}
Çıktısı
### struct as a pointer ###
{
"Network": "10.1.1.0",
"Mask": 24
}
Buradaki kodla oynayın .
Çöpü severim .
Benioku dosyalarından:
type Person struct {
Name string
Age int
Parent *Person
}
litter.Dump(Person{
Name: "Bob",
Age: 20,
Parent: &Person{
Name: "Jane",
Age: 50,
},
})
Sdump
testlerde oldukça kullanışlıdır:
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 Library kullanmanızı tavsiye ederim . Böylece herhangi bir yapıyı çok kolay bir şekilde yazdırabilirsiniz.
Kitaplığı Yükle
veya
go get github.com/kr/pretty
Şimdi kodunuzda bunu yapı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.
}
Ayrıca bu kütüphane aracılığıyla bileşen ve daha fazlası arasında fark elde edebilirsiniz. Ayrıca burada Dokümanlar kitaplığına da göz atabilirsiniz .
pretty.Formatter
Daha karmaşık yapılarınız olduğunda, yazdırmadan önce JSON'a dönüştürmeniz gerekebilir:
// Convert structs to JSON.
data, err := json.Marshal(myComplexStruct)
fmt.Printf("%s\n", data)
Kodun tamamını görmek için burayı ziyaret edin . Burada ayrıca tam kodun çalıştırılabileceği bir çevrimiçi terminal için bir bağlantı bulacaksınız ve program yapının bilgilerinin nasıl çıkarılacağını temsil eder (alanın adı ve değeri). Aşağıda yalnızca alan adlarını yazdıran program snippet'i bulunmaktadır.
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
*/
İşaretçi özyinelemesini ve dize ve int haritaları için çok sayıda anahtar sıralamasını işleyen go-render da vardır .
Kurulum:
go get github.com/luci/go-render/render
Misal:
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))
Hangi baskılar:
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)
Ayrıntıları yazdırmanın temel yolu budur
Başka bir yol, toString
struct alan adında bir işlev oluşturmak , alanları istediğiniz gibi biçimlendirmektir.
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
arayüzü uygulayabilirsiniz . Şöyle bir şey olurdu: 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) }
Harici kütüphaneler kullanmadan ve her alandan sonra yeni satırla:
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)
}
}
çok basit Veri ve Taahhüt yapısına sahip değilim.
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)
}
Öğrenmek için buradan yardım alabilirsiniz: https://gobyexample.com/structs
Belki bu üretim istekleri için uygulanmamalıdır, ancak hata ayıklama modundaysanız aşağıdaki yaklaşımı izlemenizi öneririm.
marshalledText, _ := json.MarshalIndent(inputStruct, "", " ")
fmt.Println(string(marshalledText))
Bu, verilerin okunabilirliği artırılarak json formatında biçimlendirilmesi ile sonuçlanır.
Bu paketlerin çoğu, bu tür şeyleri mümkün kılmak için yansıtma paketine dayanmaktadır.
fmt.Sprintf (), standart lib için -> func (p * pp) printArg (arg arabirimi {}, fiil rune) kullanıyor
638 numaralı satıra gidin -> https://golang.org/src/fmt/print.go
Yansıma:
https://golang.org/pkg/reflect/
Örnek kod:
https://github.com/donutloop/toolkit/blob/master/debugutil/prettysprint.go
fmt.Println("%+v", structure variable)
Bunu yapmanın daha iyi bir yolu, "commons" (belki) adlı bir pakette "% + v" dizesi için global bir sabit oluşturmak ve kodunuzun her yerinde kullanmaktır.
//In commons package
const STRUCTURE_DATA_FMT = "%+v"
//In your code everywhere
fmt.Println(commons.STRUCTURE_DATA_FMT, structure variable)
Println
işlev bir biçim dizesi argümanını kabul etmiyor. Küresel bir sabitin daha iyi olduğunu söylüyorsunuz, ancak neden belirgin yanıttan daha iyi olduğunu haklı göstermediniz. İyi bilinen bir biçim dizesi için standart olmayan bir etiket oluşturdunuz. Etiket çok daha uzun, hatırlanması zor ve kodunuz üzerinde çalışan hiç kimse bunu kullanmaz. Hem ALL_CAPS hem de her golang linterinin şikayet edeceği bir alt çizgi kullanır. Sözleşme mixedCaps
golang.org/doc/effective_go.html#mixed-caps Bu yanıtı kaldırmak için muhtemelen en iyisidir.
fmt.Println
.