2013-10-28 103 views

回答

34

encoding/json軟件包中沒有將字段設置爲「required」的標籤。您將不得不編寫自己的MarshalJSON()方法,或者對丟失的字段進行檢查。

要檢查是否有遺漏的字段,你將不得不使用指針,以便丟失/空和零值來區分:

type JsonStruct struct { 
    String *string 
    Number *float64 
} 

全部工作示例:

package main 

import (
    "fmt" 
    "encoding/json" 
) 

type JsonStruct struct { 
    String *string 
    Number *float64 
} 

var rawJson = []byte(`{ 
    "string":"We do not provide a number" 
}`) 


func main() { 
    var s *JsonStruct 
    err := json.Unmarshal(rawJson, &s) 
    if err != nil { 
     panic(err) 
    } 

    if s.String == nil { 
     panic("String is missing or null!") 
    } 

    if s.Number == nil { 
     panic("Number is missing or null!") 
    } 

    fmt.Printf("String: %s Number: %f\n", *s.String, *s.Number) 
} 

Playground

+1

或者你可以檢查默認值,這對大多數情況來說可能是足夠的(除非你使用數字)。 – Matt3o12

+0

但是如果「必填字段」的值是默認值呢? – AJPennster

+0

如果數字的必填字段可能爲0,並且您還需要檢查其是否提供,則使用字符串的替代方法來檢查沒有輸入,然後將字符串轉換爲數字。 – Zanven

2

您也可以覆蓋特定類型的解組(而不必將該字段設置爲指針,從而將必填字段隱藏在幾個json圖層中)。

type EnumItem struct {                        
    Named                           
    Value string                         
}                             

func (item *EnumItem) UnmarshalJSON(data []byte) (err error) {              
    required := struct {                       
     Value *string `json:"value"`                    
    }{}                           
    all := struct {                        
     Named                          
     Value string `json:"value"`                    
    }{}                           
    err = json.Unmarshal(data, &required)                   
    if err != nil {                        
     return                          
    } else if required.Value == nil {                    
     err = fmt.Errorf("Required field for EnumItem missing")             
    } else {                          
     err = json.Unmarshal(data, &all)                   
     item.Named = all.Named                      
     item.Value = all.Value                      
    }                            
    return                           
}