type Article struct { Id string `json:"id"` Name string `json:"name,omitempty"` Desc string `json:"desc,omitempty"` }
Problèmes
Mais cette représentation pose de sérieux problèmes, notamment pour les opérations de mise à jour ou d'édition .Par exemple, supposons que les données JSON de la demande de mise à jour ressemblent à ceci{"id":"1234","name":"xyz","desc":""}
func Test_JSON1(t *testing.T) { jsonData:=`{"id":"1234","name":"xyz","desc":""}` req:=Article{} _=json.Unmarshal([]byte(jsonData),&req) fmt.Printf("%+v",req) }Output: === RUN Test_JSON1 {Id:1234 Name:xyz Desc:}
func Test_JSON2(t *testing.T) { jsonData:=`{"id":"1234","name":"xyz"}` req:=Article{} _=json.Unmarshal([]byte(jsonData),&req) fmt.Printf("%+v",req) }Output: === RUN Test_JSON2 {Id:1234 Name:xyz Desc:}
Eh bien, Desc sera toujours obtenu sous forme de chaîne vide, alors comment faire la distinction entre les champs non définis et les champs videsréponse courte ? Pointeur
la solution
est soumise à certaines bibliothèques Comment faire la différence entre les champs vides et les champs non définis lors de lutilisation de JSON dans Golanglang existantes inspirées, telles quego-github. Nous pouvons changer les champs de structure en types de pointeur comme indiqué ci-dessous
type Article struct { Id string `json:"id"` Name *string `json:"name,omitempty"` Desc *string `json:"desc,omitempty"` }
nil).En revanche, si le champ existe et est nul, alors le pointeur n'est pas nul et le champ contient une valeur nulle.
Remarque- Je n'ai pas modifié le champ 'Id' en un type de pointeur car il n'a pas de statut vide et l'identifiant est requis, similaire à l'identifiant dans le base de données.Essayons à nouveau.
func Test_JSON_Empty(t *testing.T) { jsonData := `{"id":"1234","name":"xyz","desc":""}` req := Article{} _ = json.Unmarshal([]byte(jsonData), &req) fmt.Printf("%+v\n", req) fmt.Printf("%s\n", *req.Name) fmt.Printf("%s\n", *req.Desc) } func Test_JSON_Nil(t *testing.T) { jsonData := `{"id":"1234","name":"xyz"}` req := Article{} _ = json.Unmarshal([]byte(jsonData), &req) fmt.Printf("%+v\n", req) fmt.Printf("%s\n", *req.Name) }
Output
=== RUN Test_JSON_Empty {Id:1234 Name:0xc000088540 Desc:0xc000088550} Name: xyz Desc: --- PASS: Test_JSON_Empty (0.00s)=== RUN Test_JSON_Nil {Id:1234 Name:0xc00005c590 Desc:<nil>} Name: xyz --- PASS: Test_JSON_Nil (0.00s)
Descet contient la valeur d'une chaîne vide. Dans le second cas, le champ n'est pas défini, et on obtient un pointeur de chaîne de caractère nul.
On peut donc distinguer. entre deux mises à jour. Cette méthode s'applique non seulement aux chaînes, mais également à tous les autres types de données, y compris les entiers, les structures imbriquées, etc.
Mais cette approche pose quelques problèmes.
Sécurité nulle : Les types de données sans pointeur sont intrinsèquement sûrs pour les valeurs nulles. Dans Comment faire la différence entre les champs vides et les champs non définis lors de lutilisation de JSON dans Golanglang, cela signifie que les chaînes ou les entiers ne peuvent jamais être nuls. Mais si des pointeurs sont définis, ces types de données sont par défaut nuls. défini manuellement. Par conséquent, les tentatives d'accès à ces pointeurs sans vérifier les données de nullité peuvent provoquer le blocage de l'application.# 以下代码将崩溃, 因为 desc 为空
func Test_JSON_Nil(t *testing.T) {
jsonData := `{"id":"1234","name":"xyz"}`
req := Article{}
_ = json.Unmarshal([]byte(jsonData), &req)
fmt.Printf("%+v\n", req)
fmt.Printf("%s\n", *req.Desc)
}
: Comme vous l'avez peut-être remarqué dans la sortie des solutions basées sur un pointeur, la valeur du pointeur n'est pas imprimée. Vingt imprime la valeur hexadécimale du pointeur, ce qui est peu. utilisation dans l'application . Cela peut également être surmonté en réutilisant l'interface stringer.func (a *Article) String() string {
output:=fmt.Sprintf("Id: %s ",a.Id)
if a.Name!=nil{
output+=fmt.Sprintf("Name: '%s' ",*a.Name)
}
if u.Desc!=nil{
output+=fmt.Sprintf("Desc: '%s' ",u.Desc)
}
return output
}
:
Une autre façon de résoudre le problème ci-dessus est utiliser nullable Une bibliothèque tierce de types dont les types peuvent fournir des méthodes pour vérifier s'ils sont nuls sans se soucier des pointeurs.Adresse de traduction : https://learnku.com/go/t/49332
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!