2016-11-04 11 views
7

chcę uzyskać ciąg, który reprezentuje json jak ten:Konwersja ciąg json lub struktury w GoLang

{ "głosy": { "option_A": "3"}}

i obejmują "liczyć" klucz w nim tak kończy się tak:

{ "głosy": { "option_A": "3"}, "count": "1"}

Dlatego planowałem przekonwertować go na json, więc mogłem dodać liczbę, a następnie zrobić z niej ciąg znaków. Problem polega na tym, że nie znam struktury tego json'a, więc nie mogę użyć json.Unmarshal(in, &myStruct), ponieważ ta struktura jest różna. Jak mogę to zrobić? Dziękuję bardzo

+0

W myStruct, opisywanie zmienna count być pominięte, jeśli nie występuje. Dodaj to przed twoją zmienną 'json:", omitempty "' – Aus

+0

Nie mam definicji MyStruct, ponieważ może to być absolutnie wszystko. Potrzebuję tylko dołączyć ten klucz licznika do każdego jsonu, który reprezentuje ciąg znaków. Ale dzięki za komentarz. –

Odpowiedz

12

Naprawdę potrzebujesz tylko jednej struktury, a jak wspomniano w komentarzach poprawne adnotacje na polu przyniosą pożądane wyniki. JSON nie jest jakimś niezwykle wariantowym formatem danych, jest dobrze zdefiniowany i każdy kawałek jsona, bez względu na to, jak skomplikowany i mylący może być dla ciebie, może być reprezentowany dość łatwo iz 100% dokładnością zarówno przez schemat, jak i obiekty w Go i większość innych języków programowania OO. Oto przykład;

package main 

import (
    "fmt" 
    "encoding/json" 
) 

type Data struct { 
    Votes *Votes `json:"votes"` 
    Count string `json:"count,omitempty"` 
} 

type Votes struct { 
    OptionA string `json:"option_A"` 
} 

func main() { 
    s := `{ "votes": { "option_A": "3" } }` 
    data := &Data{ 
     Votes: &Votes{}, 
    } 
    err := json.Unmarshal([]byte(s), data) 
    fmt.Println(err) 
    fmt.Println(data.Votes) 
    s2, _ := json.Marshal(data) 
    fmt.Println(string(s2)) 
    data.Count = "2" 
    s3, _ := json.Marshal(data) 
    fmt.Println(string(s3)) 
} 

https://play.golang.org/p/ScuxESTW5i

Bazując na swoim najnowszym komentarzu można rozwiązać, że stosując interface{} do reprezentowania danych oprócz liczenia, dzięki czemu liczą ciąg io resztę blob wsadził do interface{} który zaakceptuje zasadniczo wszystko. Mówiąc to, Go jest statycznie napisanym językiem z dość ścisłym systemem i powtarzając, twoje komentarze stwierdzające "to może być wszystko" nie są prawdziwe. JSON nie może być niczym. Dla każdego elementu JSON istnieje schemat, a pojedynczy schemat może definiować wiele różnych odmian JSON. Radzę ci poświęcić trochę czasu na zrozumienie struktury danych, zamiast zhakować coś razem pod pojęciem, że nie da się go zdefiniować, kiedy to absolutnie możliwe i prawdopodobnie jest całkiem łatwe dla kogoś, kto wie, co robi.

+1

uwaga boczna: w JSON zostaną uwzględnione tylko wielkie litery w strukturze. Prywatne atrybuty zostaną zignorowane przez marshallera –

19
package main 

import "encoding/json" 

func main() { 
    in := []byte(`{ "votes": { "option_A": "3" } }`) 
    var raw map[string]interface{} 
    json.Unmarshal(in, &raw) 
    raw["count"] = 1 
    out, _ := json.Marshal(raw) 
    println(string(out)) 
} 

https://play.golang.org/p/QUyL3cyTAC

+3

eleganckiego! i łatwe do zrozumienia – NinjaGaiden

+0

Bardzo ładne, bez żadnych potrzebnych struktur i na temat! – Nebulosar