Types Go等效于inheritace类型(通过接口进行gob编码/解码)
我正在尝试编写一个函数,对各种类型的消息进行编码/解码 在OO语言中,我会使用类型继承,但Go没有这个概念,ref:,因此,这里我尝试使用标记接口样式来利用接口继承来实现这一目的 错误来自golang org src/encoding/gob/decode.go:Types Go等效于inheritace类型(通过接口进行gob编码/解码),types,go,polymorphism,Types,Go,Polymorphism,我正在尝试编写一个函数,对各种类型的消息进行编码/解码 在OO语言中,我会使用类型继承,但Go没有这个概念,ref:,因此,这里我尝试使用标记接口样式来利用接口继承来实现这一目的 错误来自golang org src/encoding/gob/decode.go: line 1019// Common confusing case: local interface type, remote concrete type. 。。是的,我觉得这很困惑 运行这个 我不能让它工作,我做错了什么?救
line 1019// Common confusing case: local interface type, remote concrete type.
。。是的,我觉得这很困惑
运行这个
我不能让它工作,我做错了什么?救命啊
更新:
我还尝试gob.Registerm1,但没有效果
我已经研究了类型嵌入,但它没有做我试图做的事情,正如您在这个例子中看到的,我已经从jcbwlkr的代码中修改过:https//play.golang.org/p/P6AwVQqQcM也要知道我可能有几十种/数百种消息类型
很可能是我找错了方向,我需要抛开我如何思考这个问题的整个想法,但这就是我目前正在努力做的:学习如何在Go和OO思维中思考。使用类型嵌入是可行的,但我必须创建一个主类型,该主类型嵌入了其中所有可能的类型:gob使解码成为可能,类型开关让我看到我得到了什么,但这一切都让我感到非常害怕和不安
我已经习惯了静态和动态语言,所以我对duck类型很满意,但这感觉就像一个中途之家,没有任何一方的舒适
我在这里要问两件事:
如何解决这个特殊问题(了解可能发生的情况)
具有接口,以及
设计方案和类型嵌入是必要的
其中之一,因此感谢您突出显示:。
在这里;这是坏代码:
package main
import (
"fmt"
"bytes"
"log"
"encoding/gob"
)
type Msger interface {
IsMsg()
}
type ClientMsg struct {
Id string
}
type ServerMsg struct {
Id string
}
func (m ClientMsg) IsMsg() { }
func (m ServerMsg) IsMsg() { }
func encode(m Msger) (bb bytes.Buffer) {
enc := gob.NewEncoder(&bb)
err := enc.Encode(m)
if err != nil {
log.Fatal("Cannot encode! err=", err)
}
return
}
func decode(m Msger, bb bytes.Buffer) { // for A
//func decode(m *Msger, bb bytes.Buffer) { // for B, C
dec := gob.NewDecoder(&bb)
err := dec.Decode(&m)
if err != nil {
log.Fatal("Cannot decode Msg! err=", err)
}
return
}
func main() {
m1 := ClientMsg{"id_1"}
b1 := encode(m1)
p_bb := bytes.NewBuffer(b1.Bytes())
var mDecoded ClientMsg // for A, B, C
//var mDecoded interface{} // D: : cannot use mDecoded (type interface {}) as type Msger in argument to decode: interface {} does not implement Msger (missing IsMsg method)
decode(mDecoded, *p_bb) // A: gives: Cannot decode Msg! err=gob: local interface type *main.Msger can only be decoded from remote interface type; received concrete type ClientMsg = struct { Id string; }
//decode(mDecoded, *p_bb) // B: gives: cannot use mDecoded (type ClientMsg) as type *Msger in argument to decode: *Msger is pointer to interface, not interface
//decode(&mDecoded, *p_bb) // C: gives: cannot use &mDecoded (type *ClientMsg) as type *Msger in argument to decode: *Msger is pointer to interface, not interface
fmt.Printf("m1 Decoded='%v'\n", mDecoded)
}
与使用标记接口不同,我将采用一种使用的方法,并将encode/decode方法放在Msg类型上
您可以使用一些新的方法来创建ClientMsg或ServerMsg结构,从而使代码更漂亮。您是否还需要将encode返回值传递给bytes.NewBuffer,或者您可以按原样使用它?发现编码接口需要对指针进行编码,但仍然无法正确解码!ref Hi jcbwlkr-感谢您的反馈,我已经研究了类型嵌入,但它并没有完成我试图做的事情,正如您在这个示例中看到的,我从您的代码中修改了:@SigridHaughty我明白您的意思。我觉得这里有一个解决方案,但我还没有看到。祝你好运!
package main
import (
"bytes"
"encoding/gob"
"fmt"
"log"
)
type Msg struct {
Id string
}
type ClientMsg struct {
Msg
}
type ServerMsg struct {
Msg
}
func (m *Msg) encode() (bb bytes.Buffer) {
enc := gob.NewEncoder(&bb)
err := enc.Encode(m)
if err != nil {
log.Fatal("Cannot encode! err=", err)
}
return
}
func (m *Msg) decode(bb *bytes.Buffer) {
dec := gob.NewDecoder(bb)
err := dec.Decode(m)
if err != nil {
log.Fatal("Cannot decode Msg! err=", err)
}
return
}
func main() {
// Make a message and encode it to a bytes.Buffer
m1 := &ClientMsg{Msg{"id_1"}}
b1 := m1.encode()
p_bb := bytes.NewBuffer(b1.Bytes())
// Make a new message and decode the bytes.Buffer from the first
m2 := &ClientMsg{Msg{}}
m2.decode(p_bb)
fmt.Printf("m2 Decoded = '%v'\n", m2.Msg.Id)
}