Как печатать структурные переменные в консоли?

Как я могу напечатать (в консоли) 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. В этом вы можете распечатать любую структуру очень легко.

  1. Установить библиотеку

    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)