2013-05-05 71 views
2

我嘗試使用labix.org/v2/mgo軟件包填充導出的結構域,其中的內容從MongoDb數據庫中獲取。防止mgo/bson Unmarshal清除未導出的字段

mgo使用labix.org/v2/mgo/bson包解組數據。但unmarshaller將所有未導出的字段設置爲零值。

有什麼辦法可以防止這種行爲?

工作實施例:

package main 

import (
    "fmt" 
    "labix.org/v2/mgo/bson" 
) 

type Sub struct{ Int int } 

type Player struct { 
    Name  string 
    unexpInt int 
    unexpPoint *Sub 
} 

func main() { 
    dta,err := bson.Marshal(bson.M{"name": "ANisus"}) 
    if err != nil { 
     panic(err) 
    } 

    p := &Player{unexpInt: 12, unexpPoint: &Sub{42}} 

    fmt.Printf("Before: %+v\n", p) 
    err = bson.Unmarshal(dta, p) 
    if err != nil { 
     panic(err) 
    } 
    fmt.Printf("After: %+v\n", p) 
} 

輸出:

Before: &{Name: unexpInt:12 unexpPoint:0xf84005f500} 
After: &{Name:ANisus unexpInt:0 unexpPoint:<nil>} 
+0

我不認爲bson會將字段設置爲零值。它使用反射,並且在Go未導出的字段中不能使用反射設置。我敢打賭,它將用一個全新的Player結構代替* Player,這會導致未導出的字段被設置爲零值。我懷疑你有什麼可以做的。 – 2013-05-06 03:57:46

+0

在我的示例中,我只將指針傳遞給'bson.Unmarshal'。當它仍指向相同的內存地址時,如何獲得新的Player結構? – ANisus 2013-05-06 06:32:31

+0

['Marshal()'](http://godoc.org/labix.org/v2/mgo/bson#Marshal)和['Unmarshal()'](http://godoc.org/labix.org/ v2/mgo/bson#Unmarshal)返回錯誤,您應該檢查它們! – thwd 2013-05-06 07:08:39

回答

1

這是不可能的。正如你可以看到in the source code,struct的值在填寫任何字段之前明確地被設置爲它們的零值。

沒有禁用此行爲的選項。這大概是爲了確保Unmarshal()的結果只取決於BSON數據而不是任何先前的狀態。

+0

你確實是。與Jeremy wall一樣,我的印象是未報告的字段無法更改:「[值只有在可尋址時才能更改,並且不能通過使用未導出的結構字段獲得。](http:// golang .ORG /包裝/反映出/#Value.CanSet)」。但是,你可以將整個結構設置爲零。很高興知道! – ANisus 2013-05-08 06:26:01