亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

基于對象何時轉換為指針(有時是指針,有時是映射)更改解組功能

基于對象何時轉換為指針(有時是指針,有時是映射)更改解組功能

Go
小唯快跑啊 2023-06-01 15:01:35
我正在實現一些序列化對象的方法(標準庫中可能已經存在,但我想要體驗)。我能夠讓 json.Marshal 和 json.Unmarshal 正確地將我的數據轉換為字符串,然后讀回一個對象,但我注意到一些我想更好地理解的有趣行為。為了測試 json 包的功能,我創建了一個測試結構:type Test struct{    T int    S string    F float32}跑步o := Test{32, "struct", 12.07}b, e := json.Marshal(o)fmt.Println(string(b), e)印刷{"T":32,"S":"struct","F":12.07} <nil>這是我所期望的。但是,在解組時我能夠得到兩個不同的結果,具體取決于我何時將對象轉換為指針:// Test 1var o2 interface{} = &oe = json.Unmarshal(b, o2)fmt.Println(o2, e)印刷// Output 1&{32 struct 12.07} <nil>同時將 o2 定義為值而不是指針,然后使用 &o2 調用 Unmarshal,即。// Test 2var o2 interface{} = oe = json.Unmarshal(b, &o2)fmt.Println(o2, e)印刷// Output 2map[T:32 S:struct F:12.07] <nil>有趣的是,所有四個// Test 3var o2 Test = oe = json.Unmarshal(b, &o2)fmt.Println(o2, e),// Test 4var o2 *Test = &oe = json.Unmarshal(b, &o2)fmt.Println(*o2, e),// Test 5var o2 *Test = &oe = json.Unmarshal(b, o2)fmt.Println(o2, e), 和// Test 6var o2 *Test = &oe = json.Unmarshal(b, &o2)fmt.Println(o2, e)打印以下內容之一:// Output 3, 4{32 struct 12.07} <nil>// Output 5, 6&{32 struct 12.07} <nil>測試 1 和 2 讓我相信,當將某些東西分配給“超類”時,一些運行時信息會丟失......似乎將指向我的結構的指針分配給 o2 為 Unmarshal 函數提供了更多關于它應該讀取的內容的類型數據而不是將我的結構分配給 o2,然后將指向 o2 的指針傳遞給 Unmarshal。這有點道理;在編譯時,測試 1 將 interface{} 傳遞給 Unmarshal,而 Test 2 將指針傳遞給 interface{}。即便如此,我還是認為參數的運行時類型會是相同的(*測試)。有人可以解釋為什么 Go 會這樣工作嗎?支持我的結論的事實是,將 o2 聲明為 Test 或 *Test 允許 Unmarshal(因此接收 *Test 作為其參數)始終將我的數據讀取為結構而不是映射。奇怪的是,測試 4 和測試 6 表明將指針傳遞給指向我的結構的指針是完全可以接受的,并且 Unmarshal 正確(?)設置了結構的值。我本以為這些測試會出現運行時錯誤,因為 Unmarshal 應該嘗試取消引用雙指針并將結果指針設置為它正在讀取的序列化結構。Automatic multi-pointer dereferencing 可能只是這個功能的一個特性,但在官方文檔中并沒有提到。我不太關心后面的這些測試。我主要只對導致測試 1 和測試 2 之間的差異的原因感興趣。
查看完整描述

1 回答

?
慕容3067478

TA貢獻1773條經驗 獲得超3個贊

unmarshal 函數遍歷指針和包含指針值的接口以找到目標值。接口中的非指針值將被忽略,因為這些值不可尋址。(此描述省略了對問題不重要的細節)。

如果目標是 aninterface{}并且 JSON 是對象,則 JSON 被解組為 amap[string]interface{}并將該值存儲在接口中。

測試 1:解組的參數是*Test。unmarshal 函數遍歷指針并解碼為Test結構。

測試 2:unmarshal 的參數是指向interface{}包含Test.?unmarshal 函數遍歷指針以獲取interface{}.?Test中的值被interface{}忽略,因為它不可尋址。因為目標是 aninterface{}而 JSON 是對象,所以 JSON 被解碼為map[string]interface{}.

3、4、5 和 6 中的代碼無法編譯。假設刪除了{}以下內容,我將繼續Test。

var o2 Test = o // 3

var o2 *Test = &o // 4

var o2 *Test = &o // 5

var o2 *Test = &o // 6

測試 3 和 5:unmarshal 的參數是一個*Test.?這與#1 相同。

測試 4 和 6:參數是一個**Test.?unmarshal 函數遍歷指針并解碼到Test結構。

因為 Go 沒有任何類似“超類”的東西,所以這不是問題。


查看完整回答
反對 回復 2023-06-01
  • 1 回答
  • 0 關注
  • 145 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號