2013-01-06 76 views
7

我有一個[]uint8成員的結構體,我正在用json.Marshal寫它。麻煩的是,它將uint8 s解釋爲char s,它會輸出一個字符串而不是數組。如何將字符/ uint8數組編組爲json數組?

如果它是[]int,我可以得到它的工作,但我不想分配和複製項目,如果我可以避免它。我可以嗎?

+0

正如我在質詢時說,我使用'json.Marshal'。我的問題不是關於'fmt',而是關於'json'庫。 – Joe

+0

(我確實有一條評論,詢問我是如何輸出它的,作者在我回答後刪除了它,不妨留下我的回覆。) – Joe

回答

13

根據docs[]byte將被編碼爲Base64字符串。

「陣列和切片值編碼爲JSON陣列,除了[]字節編碼爲64位編碼串,和一個零切片編碼作爲空JSON對象」。

所以我認爲你可能需要通過實現自己的MarshalJSON方法,使一個更理想的JSON陣列編碼出你[]uint8,使您的結構實現Marshaler接口。

拿這個例子:

import "fmt" 
import "encoding/json" 
import "strings" 

type Test struct { 
    Name string 
    Array []uint8 
} 

func (t *Test) MarshalJSON() ([]byte, error) { 
    var array string 
    if t.Array == nil { 
     array = "null" 
    } else { 
     array = strings.Join(strings.Fields(fmt.Sprintf("%d", t.Array)), ",") 
    } 
    jsonResult := fmt.Sprintf(`{"Name":%q,"Array":%s}`, t.Name, array) 
    return []byte(jsonResult), nil 
} 

func main() { 
    t := &Test{"Go", []uint8{'h', 'e', 'l', 'l', 'o'}} 

    m, err := json.Marshal(t) 
    if err != nil { 
     fmt.Println(err) 
    } 
    fmt.Printf("%s", m) // {"Name":"Go","Array":[104,101,108,108,111]} 
} 

http://play.golang.org/p/Tip59Z9gqs


或者,也許一個更好的想法是創建一個新類型且具有[]uint8作爲其基本類型,使該類型Marshaler,和在你的結構中使用該類型。

import "fmt" 
import "encoding/json" 
import "strings" 

type JSONableSlice []uint8 

func (u JSONableSlice) MarshalJSON() ([]byte, error) { 
    var result string 
    if u == nil { 
     result = "null" 
    } else { 
     result = strings.Join(strings.Fields(fmt.Sprintf("%d", u)), ",") 
    } 
    return []byte(result), nil 
} 

type Test struct { 
    Name string 
    Array JSONableSlice 
} 

func main() { 
    t := &Test{"Go", []uint8{'h', 'e', 'l', 'l', 'o'}} 

    m, err := json.Marshal(t) 
    if err != nil { 
     fmt.Println(err) 
    } 
    fmt.Printf("%s", m) // {"Name":"Go","Array":[104,101,108,108,111]} 
} 

http://play.golang.org/p/6aURXw8P5d

+0

輝煌。我認爲第二種選擇是更有前途的。非常感謝。 – Joe

+0

@Joe:不客氣。而且我更新了一下,通過將'nil'切片作爲'null'處理,使它更加完整。 –

相關問題