Как объявить пустые поля json в структурах golang? - PullRequest
1 голос
/ 05 февраля 2020

Мне обычно нравится использовать указатели для примитивных типов данных в моих структурах, чтобы при их json .Marshal поля nil всегда переводились в "field": null в строке json. Но это затруднит создание нового экземпляра структуры, так как я не могу использовать литералы.
Например:

type Book struct {
  Price *float32 `json:"price"`
  Title *string `json:"title"`
  Author *string `json:"author"`
}

func main() {
    // I can't do this
    book := &Book{
        Title: "Book1",
    }
}

Как вы можете видеть, когда я использую указатель строки, я могу ' t легко инициализировать структуру, если я не объявлю переменную для каждого поля указателя и не назначу их полям структуры. Возможно ли иметь как обнуляемые поля json, так и простоту инициализации структур без объявления дополнительных переменных?

Ответы [ 2 ]

2 голосов
/ 05 февраля 2020

Добавьте вспомогательную функцию в ваше приложение:

func NewString(s string) *string {
    return &s
}

И затем вы можете использовать литералы:

// You can do this:
book := &Book{
    Title: NewString("Book1"),
}

Существуют также библиотеки, предоставляющие эти функции NewXXX(), так что вы не можете их нужно добавить (например, github.com/icza/gox/builtinx, раскрытие: я автор).

См. по теме: Как мне сделать литерал * int64 в Go

1 голос
/ 05 февраля 2020

Есть некоторые проблемы с вашей инициализацией:

  • type Books - недопустимый способ объявления структуры (исправлено)

  • Вы пытаетесь присвоить простой string для pointer

Пример решения:

type Book struct {
    Price  *float32 `json:"price"`
    Title  *string  `json:"title"`
    Author *string  `json:"author"`
}

func main() {
    bookTitle := "Book1"
    // I can't do this
    book := &Book{
        Title: &bookTitle,
    }
}

Другой подход для решения проблема в том, чтобы создать Constructor:

type Book struct {
    Price  *float32 `json:"price"`
    Title  *string  `json:"title"`
    Author *string  `json:"author"`
}

func (b *Book) Book(title string){
    b.Title = &title    
}


func main() {
    var book Book
    fmt.Printf("%+v\n", book)
    book.Book("Book1")
    fmt.Printf("%+v\n", book)
}

Результат будет примерно таким:

{Price:<nil> Title:<nil> Author:<nil>}
{Price:<nil> Title:0xc00003e1f0 Author:<nil>}
...