2015-10-17 158 views
4

有沒有一種方法來序列化一個結構的空數組屬性(非空),並反序列化爲一個空數組返回(不再空)?Golang序列化/反序列化一個空陣列不爲空

考慮到空數組實際上是一個指向null的指針,空數組和指向null的指針之間的可感知的初始差異在serialize/deserialize之後完全丟失了嗎?

最糟糕的實際情況是當我第一次向我的REST客戶端顯示一個空數組屬性時,作爲json「att」:[],並且在緩存註冊到redis和recover後,顯示相同的屬性我的客戶作爲「att」:null,導致合同中斷和很多混淆。

總結:可以顯示客戶2點的地址等的JSON空數組,序列化/反序列化後=>https://play.golang.org/p/TVwvTWDyHZ

+3

在Go中,[數組和**片**是非常不同的東西](https://blog.golang.org/slices)。你幾乎肯定意味着後者。 –

回答

5

我敢肯定你能做到這一點的最簡單的方法是改變你的線

var cust1_recovered Customer 

cust1_recovered := Customer{Addresses: []Address{}} 

除非我錯誤地讀你的問題,我相信這是你想要的輸出:

ORIGINAL Customer 2 { 
    "Name": "Customer number 2", 
    "Addresses": [] 
} 
RECOVERED Customer 2 { 
    "Name": "Customer number 2", 
    "Addresses": [] 
} 

這裏是驗證的操場:https://play.golang.org/p/T9K1VSTAM0

這裏的限制,如@mike指出,如果是是Addresses真正nil你編碼之前,一旦你解碼你沒有得到的JSON相當於null,而是會用一個空列表結束。

+0

不知道爲什麼這是倒票。它做OP所要求的,返回一個空的json數組來代替null。 – sberry

+1

不是downvoter,但我會假設,因爲它實際上並沒有區分這兩者。如果它最初是'nil',現在就是'[]'。 –

+2

@MikePrecup:除非我錯誤地閱讀OP的問題,否則我認爲這就是他們之後的事情。 – sberry

3

沒有,這是不可能的。要理解爲什麼,我們來看看Go規範。爲了輸出兩個不同的結果,空白與零,任何序列化方法將需要能夠告訴兩者之間的差異。然而,根據Go規格,

如果兩個陣列類型具有相同的元素類型和相同的數組長度,則它們是相同的。

由於既不包含任何元素並具有相同的元件類型,唯一的區別可以是在長度上,但它也指出

一個nil切片的長度,地圖或信道是0

所以通過比較,它將無法辨別。當然,除了比較之外,還有其他方法,所以要真正把指甲放在棺材裏,這裏是顯示它們具有相同底層表示的部分。該規範還保證

結構或陣列型具有大小零,如果它不包含任何字段(或 元件,分別地)具有一個大小大於零。

因此零長度數組的實際分配結構必須大小爲零。如果它的大小爲零,它不能存儲關於它是空的還是nil的任何信息,所以對象本身也不知道。總之,nil數組和零長度數組之間沒有區別。

在序列化/反序列化期間,「空數組和空指針之間的可察覺的初始差異」在初始分配完成之後不會丟失。

+0

Up'd,因爲這實際上是如何工作的。請參閱我的回答中的@ mike評論,以瞭解我的解決方案的侷限性。 – sberry

+0

使用指向切片的指針怎麼樣?就像你會做一個指向字符串的指針,所以它可以是零?那可能嗎? – tothemario