我有一個[]uint8
成員的結構體,我正在用json.Marshal
寫它。麻煩的是,它將uint8
s解釋爲char
s,它會輸出一個字符串而不是數組。如何將字符/ uint8數組編組爲json數組?
如果它是[]int
,我可以得到它的工作,但我不想分配和複製項目,如果我可以避免它。我可以嗎?
我有一個[]uint8
成員的結構體,我正在用json.Marshal
寫它。麻煩的是,它將uint8
s解釋爲char
s,它會輸出一個字符串而不是數組。如何將字符/ uint8數組編組爲json數組?
如果它是[]int
,我可以得到它的工作,但我不想分配和複製項目,如果我可以避免它。我可以嗎?
根據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]}
}
輝煌。我認爲第二種選擇是更有前途的。非常感謝。 – Joe
@Joe:不客氣。而且我更新了一下,通過將'nil'切片作爲'null'處理,使它更加完整。 –
正如我在質詢時說,我使用'json.Marshal'。我的問題不是關於'fmt',而是關於'json'庫。 – Joe
(我確實有一條評論,詢問我是如何輸出它的,作者在我回答後刪除了它,不妨留下我的回覆。) – Joe