Перетворення структури Go в JSON


181

Я намагаюся перетворити структуру Go в JSON за допомогою jsonпакету, але все, що я отримую, це {}. Я впевнений, що це щось абсолютно очевидно, але я цього не бачу.

package main

import (
    "fmt"
    "encoding/json"
)

type User struct {
    name string
}

func main() {
    user := &User{name:"Frank"}
    b, err := json.Marshal(user)
    if err != nil {
        fmt.Printf("Error: %s", err)
        return;
    }
    fmt.Println(string(b))
}

Потім, коли я намагаюся запустити його, я отримую таке:

$ 6g test.go && 6l -o test test.6 && ./test 
{}

Відповіді:


331

Вам потрібно експортувати в User.nameполе , так що jsonпакет може побачити його. Перейменуйте nameполе на Name.

package main

import (
    "fmt"
    "encoding/json"
)

type User struct {
    Name string
}

func main() {
    user := &User{Name: "Frank"}
    b, err := json.Marshal(user)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(string(b))
}

Вихід:

{"Name":"Frank"}

87
Зауважте, що ви можете додати `json:"name"`до кінця визначення структури структури, щоб зберегти назву виводу.
Дастін

12
Я бачу. Мені якось подобається мова, але я думаю, що деякі синтаксичні елементи йдуть далеко. Якщо ім'я члена структури визначає поведінку, то це просто неправильно.
magiconair

1
Ну а наявність імені визначає поведінку, можна обговорити, якщо це добре чи погано :), але це впевнено полегшить дізнатися, чи поле експортується чи ні, не перевіряючи десь ще.
Олоф

6
@magiconair: Капіталізація першої руни визначає видимість , є набагато розумнішою ідеєю, ніж "ім'я члена структури визначає поведінку" . Метадані видимості потрібно десь зберігати та потребує синтаксису для їх вираження. Врешті-решт було встановлено, що співпраця з капіталізацією перших знаків найкраще працює з найменшими комерційними компромісами. До випуску Go1 інші схеми були випробувані та відхилені.
deft_code

11
Я пройшов довгий шлях, і зараз дуже подобається мова, включаючи експорт з великої літери.
магіконар

62

Пов'язані питання:

У мене виникли проблеми з перетворенням структури в JSON, надсилаючи її як відповідь від Golang, а потім пізніше виловити те саме в JavaScript через Ajax.

Витратили багато часу, тому тут розміщуємо рішення.

У роботі:

// web server

type Foo struct {
    Number int    `json:"number"`
    Title  string `json:"title"`
}

foo_marshalled, err := json.Marshal(Foo{Number: 1, Title: "test"})
fmt.Fprint(w, string(foo_marshalled)) // write response to ResponseWriter (w)

У JavaScript:

// web call & receive in "data", thru Ajax/ other

var Foo = JSON.parse(data);
console.log("number: " + Foo.number);
console.log("title: " + Foo.title);

Сподіваюся, що це комусь допоможе.
Удачі.


6

Значення структури кодують як об'єкти JSON. Кожне експортоване структурове поле стає членом об'єкта, якщо:

  • тег поля "-" або
  • поле порожнє, і його тег вказує параметр "пропустити порожній".

Порожні значення - помилкові, 0, будь-які нульові вказівники чи значення інтерфейсу, а також будь-який масив, фрагмент, карта чи рядок довжиною нульової. Рядок ключа за замовчуванням об'єкта - це ім'я поля stru, але може бути вказане у значенні тега поля stru. Ключ "json" у значенні тега поля Stru - це ім'я ключа, а потім - необов'язкова кома та параметри.


2

Ви можете визначити власні спеціальні методи MarshalJSON та UnmarshalJSON і навмисно контролювати те, що слід включити, наприклад:

package main

import (
    "fmt"
    "encoding/json"
)

type User struct {
    name string
}

func (u *User) MarshalJSON() ([]byte, error) {
    return json.Marshal(&struct {
        Name     string `json:"name"`
    }{
        Name:     "customized" + u.name,
    })
}

func main() {
    user := &User{name: "Frank"}
    b, err := json.Marshal(user)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(string(b))
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.