Go 에서 JSON 이 자주 쓰 는 팁.

json
  • struct 빈 필드 무시
  • struct 빈 필드 무시,사용omitempty
    type User struct{
         
        Email string `json:"email,omitempty"`
        Pwd  string `json:"pwd,omitempty"`
    }
    
  • 임시 접착 두 struct
  • type BlogPost struct{
         
        URL string `json:"url"`
    }
    
    type Analytics struct{
         
        Visitors int `json:"visitors"`
    }
    
    json.Marshal(struct{
         
        *BlogPost
        *Analytics
    }{
         post, analytics})
    
  • 두 개의 struct 를 임시로 절개
  • json.Unmarshal([]byte(`{
        "url":"[email protected]",
        "visitors":10
    }`), struct{
         
       *BlogPost
       *Analytics
    }{
         &post, &analytics})
    
  • 임시 개명 struct 필드
  • type Cache struct {
         
        Key    string `json:"key"`
        MaxAge int    `json:"cacheAge"`
    }
    
    json.Marshal(struct {
         
        *Cache
        OmitMaxAge int `json:"cacheAge,omitempty"` // remove bad key
        MaxAge     int `json:"max_age"` // add new key
    }{
         cache, 0, 10})
    
  • 문자열 로 숫자 전달
  • type Object struct {
         
        Num int `json:"num,string"`
    }
    
         json  {
         "num":"100"},   json  {
         "num":100}     
    
  • MarshalJSON 지원 time.Time
  • 사용
    go 기본 값 은time.Time문자열 로 정렬 합 니 다.다른 방식 으로 표시 하려 면time.Time형식 을 사용자 정의 하고 정의 해 야 합 니 다MarshalJSON
    type timeImplMarshaler time.Time
    
    func (o timeImplMarshaler) MarshalJSON() ([]byte, err) {
         
        seconds := time.Time(o).Unix()
        return []byte(strconv.FormatInt(seconds, 10)), nil
    }
    
  • RegisterTypeEncoder 지원 time.Time
  • 사용
    jsoniter 는 사용자 정의 type 이 아 닌 JSON 디 코딩 방식 을 정의 할 수 있 습 니 다.예 를 들 어time.Time에 대해 epoch int 64 직렬 화 를 사용 할 수 있 습 니 다.
    import "github.com/json-iterator/go/extra"
    
    extra.RegisterTimeAsInt64Codec(time.Microsecond)
    ouput, err := jsoniter.Marshal(time.Unix(1,1002))
    should.Equal("1000001", string(output))
    
  • 사용MarshalText,UnmarshalText비 문자열 을 key 로 지원 하 는 map
  • JSON 표준 에 서 는stringkeymap만 지원 하지만 go 는MarshalText()인 터 페 이 스 를 통 해 다른 유형 도mapkey로 사용 할 수 있 습 니 다.
    type Key struct {
         
    	Name  string `json:"name"`
    	Value string `json:"value"`
    }
    
    //        (  )
    //          json.Marshal()   
    func (k Key) MarshalText() ([]byte, error) {
         
    	data := fmt.Sprintf("%v_%v", k.Name, k.Value)
    	return []byte(data), nil
    }
    
    //         (  ),         . 
    //          json.Unmarshal()   
    func (k *Key) UnmarshalText(text []byte) (error) {
         
    	tokens := strings.Split(string(text), "_")
    	if len(tokens) == 2 {
         
    		k.Name = tokens[0]
    		k.Value = tokens[1]
    		return nil
    	}
    	return errors.New("invalid text")
    }
    
    func main() {
         
    	val := map[Key]string{
         {
         "12", "22"}: "2"}
    	data, err := json.Marshal(val)
    	fmt.Println(string(data), err)
    
    	var vv map[Key]string
    	json.Unmarshal(data, &vv)
    	fmt.Println(vv)
    }
    
    
  • json.RawMessage 사용
  • 일부 json 문서 에 표준 형식 이 없 으 면 원본 정 보 를 사용[]byte하여 저장 할 수 있 습 니 다.
    type RawObject struct {
         
    	Key string
    	Raw json.RawMessage
    }
    
    func main() {
         
    	var data RawObject
    	json.Unmarshal([]byte(`{"key":"111", "raw":[1,2,3]}`), &data)
    	fmt.Println(string(data.Raw)) // [1,2,3]
    }
    
  • json.Number 사용
  • 기본적으로interface에 대응 하 는 숫자 라면float64형식 입 니 다.입력 한 숫자 가 크 면 정밀도 가 손 상 됩 니 다.UseNumber()사용json.Number을 사용 하여 문자열 로 숫자 를 표시 할 수 있 습 니 다.
  • 필드 의 이름 스타일 을 통일 적 으로 변경 합 니 다
  • ① 항상 JSON 의 필드 이름과 Go 의 필드 이름 이 다 릅 니 다.field tag로 수정 할 수 있 습 니 다.
    ② 그러나 한 필드 씩 설정 하 는 것 은 너무 번 거 로 우 므 로 jsoniter 를 사용 하면 이름 스타일 을 통일 적 으로 설정 할 수 있 습 니 다.
    ①,② 의 방식 으로 JSON 의 필드 이름 을 선택 합 니 다.① 의 필드 이름 이 존재 할 경우 ① 을 사용 합 니 다.그렇지 않 으 면 다시 사용 합 니 다 ②
    type T struct {
         
    	UserName      string
    	FirstLanguage string `json:"language"`
    }
    
    extra.SetNamingStrategy(func(s string) string {
         
        return strings.ToLower(s)
    })
    d, _ := jsoniter.Marshal(T{
         })
    fmt.Println(string(d)) // {"username":"","language":""}
    
  • 개인 필드 지원
  • Go 표준 라 이브 러 리 는 Public field 만 지원 합 니 다.jsoniter 는 private field 를 추가 로 지원 합 니 다.SupportPrivateFields()를 사용 하여 열 어야 합 니 다.
    type T struct {
         
    	UserName      string
    	FirstLanguage string `json:"language"`
    	private       string
    }
    
    extra.SetNamingStrategy(func(s string) string {
         
        return strings.ToLower(s)
    })
    extra.SupportPrivateFields()
    
    var val T
    jsoniter.Unmarshal([]byte(`{
       "username":"", 
       "language":"en", 
       "private":"private"
    }`), &val)
    

    좋은 웹페이지 즐겨찾기