2016-01-26 72 views
3

我有一個struct包含各種貨幣值,在仙(1/100 USD):自定義JSON解組字符串編碼數

type CurrencyValues struct { 
    v1 int `json:"v1,string"` 
    v2 int `json:"v2,string"` 
} 

我想創建一個自定義的JSON Unmarshaller的貨幣值與千分離器。這些值被編碼爲字符串,具有一個或多個分隔符(,),可能還有一個小數點(.)。

對於此JSON {"v1": "10", "v2": "1,503.21"},我想要JSON Unmarshal CurrencyValues{v1: 1000, v2: 150321}

繼類似的答案在這裏:Golang: How to unmarshall both 0 and false as bool from JSON,我繼續創建了一個自定義類型爲我的貨幣領域,其中包括自定義解組功能:

type ConvertibleCentValue int 

func (cents *ConvertibleCentValue) UnmarshalJSON(data []byte) error { 
    asString := string(data) 

    // Remove thousands separators 
    asString = strings.Replace(asString, ",", "", -1) 

    // Parse to float, then convert dollars to cents 
    if floatVal, err := strconv.ParseFloat(asString, 32); err == nil { 
     *cents = ConvertibleCentValue(int(floatVal * 100.0)) 
     return nil 
    } else { 
     return err 
    } 
} 

然而,書寫時的單元測試:

func Test_ConvertibleCentValue_Unmarshal(t *testing.T) { 
    var c ConvertibleCentValue 
    assert.Nil(t, json.Unmarshal([]byte("1,500"), &c)) 
    assert.Equal(t, 150000, int(c)) 
} 

我遇到這樣的錯誤:

Error:  Expected nil, but got: &json.SyntaxError{msg:"invalid character ',' after top-level value", Offset:2} 

我在這裏錯過了什麼?

回答

3

您試圖對字符串1,500解組,該字符串在JSON中無效。我想你的意思是解組JSON字符串"1,500"

assert.Nil(t, json.Unmarshal([]byte(`"1,500"`), &c)) 

注意反引號。這是一個簡化的例子:

b := []byte(`1,500`) 
var s string 
err := json.Unmarshal(b, &s) 
fmt.Println(s, err) // Prints error. 

b = []byte(`"1,500"`) 
err = json.Unmarshal(b, &s) 
fmt.Println(s, err) // Works fine. 

遊樂場:http://play.golang.org/p/uwayOSgmTv

+0

這是簡單的事情,讓你。謝謝。 – scooz

+1

@scooz這是簡單的事情,_will_得到雅。 ;) –