1
我試圖使用go的net/rpc包來發送數據結構。數據結構包含一個指向uint64的指針。指針永遠不會爲零,但值可能爲0.我發現當值爲0時,接收器會看到一個零指針。當該值爲非0時,接收者看到一個非零指針指向一個適當的值。這是有問題的,因爲這意味着RPC打破了我的數據結構的一個不變性:指針永遠不會爲零。golang gob將指針轉換爲0爲零指針
我有一個去遊樂場,這裏演示了此行爲:https://play.golang.org/p/Un3bTe5F-P
package main
import (
"bytes"
"encoding/gob"
"fmt"
"log"
)
type P struct {
Zero, One int
Ptr *int
}
func main() {
// Initialize the encoder and decoder. Normally enc and dec would be
// bound to network connections and the encoder and decoder would
// run in different processes.
var network bytes.Buffer // Stand-in for a network connection
enc := gob.NewEncoder(&network) // Will write to network.
dec := gob.NewDecoder(&network) // Will read from network.
// Encode (send) the value.
var p P
p.Zero = 0
p.One = 1
p.Ptr = &p.Zero
fmt.Printf("p0: %s\n", p)
err := enc.Encode(p)
if err != nil {
log.Fatal("encode error:", err)
}
// Decode (receive) the value.
var q P
err = dec.Decode(&q)
if err != nil {
log.Fatal("decode error:", err)
}
fmt.Printf("q0: %s\n", q)
p.Ptr = &p.One
fmt.Printf("p1: %s\n", p)
err = enc.Encode(p)
if err != nil {
log.Fatal("encode error:", err)
}
err = dec.Decode(&q)
if err != nil {
log.Fatal("decode error:", err)
}
fmt.Printf("q1: %s\n", q)
}
從這段代碼的輸出是:
p0: {%!s(int=0) %!s(int=1) %!s(*int=0x1050a780)}
q0: {%!s(int=0) %!s(int=1) %!s(*int=<nil>)}
p1: {%!s(int=0) %!s(int=1) %!s(*int=0x1050a784)}
q1: {%!s(int=0) %!s(int=1) %!s(*int=0x1050aba8)}
所以當ptr指向一個0,就變成在零接收端。當Ptr指向1時,它正常通過。
這是一個錯誤?有沒有解決這個問題的方法?我想避免解組在接收端我detastructure解決所有意想不到的零指針...
這看起來像一個錯誤,但它可能是gob格式的限制。如果你有一個不變的指向整數的指針永遠不會是零,那爲什麼它是一個指針? – JimB
@JimB該結構是解析JSON的結果,我需要知道字段是否存在。 Go的JSON解析庫爲此使用指針。 – user7678959