>  기사  >  백엔드 개발  >  Golang에서 JSON을 사용할 때 빈 필드와 설정되지 않은 필드를 구별하는 방법

Golang에서 JSON을 사용할 때 빈 필드와 설정되지 않은 필드를 구별하는 방법

藏色散人
藏色散人앞으로
2020-09-09 09:37:292862검색

아래에 JSON 시간 분할을 사용하는 방법과 Golang에서 JSON을 사용할 때 빈 필드와 설정되지 않은 필드를 구별하는 방법lang에서 JSON 시간 분할을 사용할 수 없는 방법을 소개하고 있으니 필요한 친구들에게 도움이 되길 바랍니다!

몇 주 전에 저는 Golang에서 JSON을 사용할 때 빈 필드와 설정되지 않은 필드를 구별하는 방법lang 마이크로서비스를 작업 중이었고 JSON 데이터를 사용하여 CURP 작업에 대한 지원을 추가해야 했습니다. 일반적으로 모든 필드가 정의되고 '생략' 속성이 있는 엔터티에 대한 구조체를 생성했습니다. 아래와 같이

type Article struct {
   Id   string      `json:"id"`
   Name string      `json:"name,omitempty"`
   Desc string      `json:"desc,omitempty"`
}
Golang에서 JSON을 사용할 때 빈 필드와 설정되지 않은 필드를 구별하는 방법

Problems

그러나 이 표현은 특히 업데이트 또는 편집 작업에 심각한 문제를 가져옵니다.예를 들어 업데이트 요청의 JSON 데이터가 다음과 같다고 가정해 보세요

{"id":"1234","name":"xyz","desc":""}

빈 설명에 주의하세요 이제 Golang에서 JSON을 사용할 때 빈 필드와 설정되지 않은 필드를 구별하는 방법

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

에서 차단 해제된 후 이 요청 데이터가 어떻게 보이는지 살펴보겠습니다. 여기 설명은 빈 문자열입니다. 분명히 클라이언트는 우리 프로그램에서 추론한 빈 문자열로 desc를 설정하려고 합니다. 그러나 클라이언트가 Desc의 기존 값을 변경하지 않으려는 경우 이 경우 설명 문자열을 다시 보내는 것은 올바르지 않으므로 요청된 JSON 데이터는 다음과 같을 수 있습니다

{"id":"1234", "name":"xyz"}

우리 구조로 풀어냅니다

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

글쎄, Desc는 여전히 빈 문자열 검색이므로 설정되지 않은 필드와 빈 필드를 구별하는 방법

짧은 대답은?

go-github
과 같은 일부 기존 Golang에서 JSON을 사용할 때 빈 필드와 설정되지 않은 필드를 구별하는 방법lang 라이브러리에서 영감을 얻었습니다. 아래와 같이 구조 필드를 포인터 유형으로 변경할 수 있습니다.

type Article struct {
   Id    string      `json:"id"`
   Name *string      `json:"name,omitempty"`
   Desc *string      `json:"desc,omitempty"`
}

이렇게 하면 필드에 추가 상태가 추가됩니다. 원본 JSON에 없으면 구조체 필드는 비어 있습니다(

nil

).

반면에 필드가 존재하고 null이면 포인터는 null이 아니며 필드에 null이 포함됩니다. NOTE

- '

Id' 필드를 포인터형으로 변경하지 않았습니다. 빈 상태에서는 데이터베이스의 ID와 유사하게 ID가 필요합니다.다시 시도해 보겠습니다.

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)

첫 번째 경우에는 desc가 빈 문자열로 설정되었으므로 Desc에서 null이 아닌 포인터를 얻었고 빈 문자열 값을 포함했습니다. 두 번째 경우에는 필드가 설정되지 않았으며 우리는

따라서 우리는 두 업데이트를 구별할 수 있습니다. 이 접근 방식은 문자열에만 적용되는 것이 아니라 정수, 중첩 구조 등을 포함한 다른 모든 데이터 유형에도 적용 가능합니다.

Null 안전성

: 포인터가 아닌 데이터 유형에는 고유한 null 안전성이 있습니다. Golang에서 JSON을 사용할 때 빈 필드와 설정되지 않은 필드를 구별하는 방법lang에서는 이는 문자열이나 정수 유형이 항상 null이 될 수 없음을 의미합니다. 이러한 데이터 유형은 수동으로 설정하지 않으면 기본적으로 null이 됩니다. 따라서 null 허용 여부를 확인하지 않고 해당 포인터의 데이터에 액세스하면 애플리케이션이 중단될 수 있습니다.
# 以下代码将崩溃, 因为 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)
}

이 문제는 항상 null 포인터를 확인하면 쉽게 해결할 수 있지만 코드에서 오류가 발생할 수 있습니다.

인쇄 가능성
: 포인터 기반 솔루션의 출력에서 ​​알 수 있듯이 Twenty는 응용 프로그램에서 거의 사용되지 않는 포인터의 16진수 값을 인쇄하지 않습니다. 이는 스트링거 인터페이스를 재사용하여 극복할 수도 있습니다.

func (a *Article) String() string {
   output:=fmt.Sprintf("Id: %s ",a.Id)
   if a.Name!=nil{
   output+=fmt.Sprintf("Name: &#39;%s&#39; ",*a.Name)
   }
   if u.Desc!=nil{
   output+=fmt.Sprintf("Desc: &#39;%s&#39; ",u.Desc)
   }
   return output
}

Appendix

:

위 문제를 해결하는 또 다른 방법은 null 허용 여부 확인을 제공하는 null 허용 유형이 있는 타사 라이브러리를 사용하는 것입니다. 포인터에 신경쓰세요.

github.com/guregu/null

github.com/google/go-github

원본 주소: https://medium.com/@arpitkh96/ Differentiate-between-empty -and- not-set-fields-with-json-in-golang-957bb2c5c065번역 주소: https://learnku.com/go/t/49332

    위 내용은 Golang에서 JSON을 사용할 때 빈 필드와 설정되지 않은 필드를 구별하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    성명:
    이 기사는 learnku.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제