Konwertowanie Go struct na JSON


181

Próbuję przekonwertować strukturę Go na JSON przy użyciu jsonpakietu, ale wszystko, co dostaję, to {}. Jestem pewien, że jest to coś całkowicie oczywistego, ale nie widzę tego.

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))
}

Potem, gdy próbuję go uruchomić, otrzymuję to:

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

Odpowiedzi:


330

Trzeba wyeksportować w User.namepole tak, że jsonpakiet może go zobaczyć. Zmień nazwę namepola na 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))
}

Wynik:

{"Name":"Frank"}

87
Zauważ, że możesz dodać `json:"name"`na końcu definicji pola struct, aby zachować nazwę wyjściową.
Dustin

12
Widzę. Trochę mi się podoba ten język, ale myślę, że niektóre elementy składniowe idą za daleko. Jeśli nazwa członka struktury określa zachowanie, jest to po prostu niepoprawne.
magiconair,

1
Cóż, posiadanie nazwy decyduje o tym, czy zachowanie może być omówione, czy jest dobre, czy złe :), ale z pewnością ułatwia sprawdzenie, czy pole jest eksportowane, czy nie, bez konieczności sprawdzania gdzie indziej.
Olof

6
@magiconair: Wielkie litery pierwszej runy decydują o widoczności , jest znacznie bardziej rozsądnym pomysłem niż: „nazwa członka struktury określa zachowanie” . Metadane widoczności muszą być gdzieś przechowywane i wymagają wyrażenia, aby je wyrazić. Ostatecznie ustalono, że wybór dużej litery pierwszego znaku najlepiej sprawdza się przy najmniejszej liczbie kompromisów. Przed wydaniem Go1 wypróbowano i odrzucono inne programy.
deft_code

11
Przeszedłem długą drogę i bardzo podoba mi się ten język, w tym eksportowanie według wielkich liter.
magiconair

62

Powiązany problem:

Miałem problem z konwersją struct na JSON, wysyłając go jako odpowiedź od Golanga, a potem złapałem to samo w JavaScript przez Ajax.

Zmarnowałem dużo czasu, więc opublikuj rozwiązanie tutaj.

In Go:

// 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)

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);

Mam nadzieję, że to komuś pomoże.
Powodzenia.


6

Wartości struktur kodowane są jako obiekty JSON. Każde wyeksportowane pole struktury staje się członkiem obiektu, chyba że:

  • znacznik pola to „-” lub
  • pole jest puste, a jego znacznik określa opcję „pomiń pusty”.

Puste wartości to false, 0, dowolny wskaźnik zerowy lub wartość interfejsu oraz dowolna tablica, plasterek, mapa lub łańcuch o długości zero. Domyślny ciąg klucza obiektu to nazwa pola strukturalnego, ale można go określić w wartości znacznika pola strukturalnego. Klucz „json” w wartości znacznika pola struct to nazwa klucza, po której następuje opcjonalny przecinek i opcje.


2

Możesz zdefiniować własne niestandardowe metody MarshalJSON i UnmarshalJSON i celowo kontrolować, co powinno być uwzględnione, np .:

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))
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.