JSON i radzenie sobie z nieuregulowanymi polami
Czy jest jakiś techniczny powód, dla którego pola nie są dołączane przez encoding / json? Jeśli nie i jest to arbitralna decyzja, czy może istnieć dodatkowa opcja tylnych drzwi (powiedzmy"+") do włączenia, nawet jeśli nie jest to możliwe?
Wymaganie eksportu kodu klienta w celu uzyskania tej funkcjonalności wydaje się niefortunne, zwłaszcza jeśli małe litery zapewniają enkapsulację lub decyzja o budowie jest znacznie późniejsza niż ich zaprojektowanie.
Jak ludzie sobie z tym radzą? Po prostu Eksportuj wszystko?
Również, czy eksportowanie nazw pól nie utrudnia podążania za sugerowanymi idiomami. Myślę, że jeśli struktura X ma pole Y, nie można mieć metody accessor Y (). Jeśli chcesz zapewnić dostęp do interfejsu Y, musisz wymyślić nową nazwę dla gettera i bez względu na to, co dostaniesz coś nie-idiomatycznego zgodnie z http://golang.org/doc/effective_go.html#Getters
2 answers
Jest powód techniczny. Biblioteka json nie ma możliwości wyświetlania pól za pomocą reflect, chyba że zostaną wyeksportowane. Pakiet może przeglądać tylko niezaksięgowane pola typów w ramach własnego pakietu
Aby poradzić sobie z Twoim problemem, możesz stworzyć Typ niewyeksportowany z wyeksportowanymi polami. Json będzie unmarshal do typu unexported, jeśli zostanie do niego przekazany bez problemu, ale nie pojawi się w dokumentach API. Następnie można utworzyć wyeksportowany typ, który osadza / align = "left" / Ten wyeksportowany Typ będzie potrzebował metod do implementacji interfejsów json.Marshaler
i json.Unmarshaler
.
Uwaga: cały kod nie jest testowany i może nawet nie być kompilowany.
type jsonData struct {
Field1 string
Field2 string
}
type JsonData struct {
jsonData
}
// Implement json.Unmarshaller
func (d *JsonData) UnmarshalJSON(b []byte) error {
return json.Unmarshal(b, &d.jsonData)
}
// Getter
func (d *JsonData) Field1() string {
return d.jsonData.Field1
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-29 07:54:01
Odpowiedź Stephena jest kompletna. Na marginesie, jeśli wszystko, co naprawdę chcesz, to małe litery w json, możesz ręcznie podać nazwę klucza w następujący sposób:
type Whatever struct {
SomeField int `json:"some_field"`
}
W ten sposób, marshaling a Whatever tworzy klucz "some_field" dla pola SomeField(zamiast "SomeField" w Twoim json).
Jeśli nie jesteś nastawiony na utrzymywanie nieprzeznaczonych pól, możesz również zaimplementować json.Interfejs marshalera poprzez zdefiniowanie metody z podpisem MarshalJSON() ([]byte, error)
. Jednym ze sposobów jest użycie literał struktury, który po prostu wyeksportował wersje nieeksportowanych pól, Jak to:
type Whatever struct {
someField int
}
func (w Whatever) MarshalJSON() ([]byte, error) {
return json.Marshal(struct{
SomeField int `json:"some_field"`
}{
SomeField: w.someField,
})
}
To może być trochę uciążliwe, więc możesz również użyć map[string]interface{}
jeśli wolisz:
func (w Whatever) MarshalJSON() ([]byte, error) {
return json.Marshal(map[string]interface{}{
"some_field": w.SomeField,
})
}
Należy jednak zauważyć, że marshaling interface{}
ma pewne zastrzeżenia i może wykonywać rzeczy takie jak marshal uint64
na pływaku, powodując utratę precyzji. (all code untested)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-28 19:41:25