- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我正在尝试编写一个函数来编码/解码各种类型的消息。
在 OO 语言中,我会使用类型继承,但 Go 没有这个概念,引用:http://golang.org/doc/faq#inheritance ,因此,我在这里尝试使用“标记接口(interface)”样式来利用接口(interface)继承来达到此目的。
错误来自golang org src/encoding/gob/decode.go:
line 1019// Common confusing case: local interface type, remote concrete type.
.. 是的,我觉得这很困惑!!
在 https://play.golang.org/p/ldEvQXIgEa 运行
我无法让它工作,我做错了什么?请帮忙!
更新:
(我也试过 gob.Register(m1) 但没有效果)。
我研究了类型嵌入,但它并没有做我想做的事情,正如你在这个例子中看到的(我已经从 jcbwlkr 的代码中修改):https//play .golang .org/p/P6AwVQqQcM(另请注意,我可能有数十种/数百种消息类型!)
很可能我找错了树,我需要放弃关于如何我思考这个问题的整个想法(但这就是我目前正在尝试做的事情:学习如何“Think in Go” vs OO thinking)。使用类型嵌入是可行的,但我必须创建一个主类型,在其中嵌入(组合)所有可能的类型:gob 使解码成为可能,类型开关让我看到我得到了什么,但这一切 < em>感觉想想 非常可怕和不舒服。
(我习惯了静态和动态语言,所以我对鸭子打字很满意,但是这感觉就像一个折衷的房子,没有两端的舒适感!)。
所以我要问两件事:
这是损坏的代码:
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)
}
最佳答案
我不使用标记接口(interface),而是采用使用 Type Embedding 的方法并将编码/解码方法放在 Msg
类型上。
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)
}
您可以使用一些 New
方法来制作 ClientMsg
或 ServerMsg
结构,从而使这段代码更好。您还需要将返回值从 encode
传递到 bytes.NewBuffer
还是可以按原样使用它?
关于types - Go 等效于类型继承(通过接口(interface)进行 gob 编码/解码),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28568275/
我正在尝试在我的代码库中为我正在编写的游戏服务器更多地使用接口(interface),并了解高级概念以及何时应该使用接口(interface)(我认为)。在我的例子中,我使用它们将我的包相互分离,并使
我有一个名为 Widget 的接口(interface),它在我的整个项目中都在使用。但是,它也用作名为 Widget 的组件的 Prop 。 处理此问题的最佳方法是什么?我应该更改我的 Widget
有一个接口(interface)可以是多个接口(interface)之一 interface a {x:string} interface b {y:string} interface c {z:st
我遇到了一种情况,我需要调用第三方服务来获取一些信息。这些服务对于不同的客户可能会有所不同。我的界面中有一个身份验证功能,如下所示。 interface IServiceProvider { bool
在我的例子中,“RequestHandlerProxy”是一个结构,其字段为接口(interface)“IAdapter”,接口(interface)有可能被调用的方法,该方法的输入为结构“Reque
我有一个接口(interface)Interface1,它已由类A实现,并且设置了一些私有(private)变量值,并且我将类A的对象发送到下一个接受输入作为Interface2的类。那么我怎样才能将
假设我有这样的类和接口(interface)结构: interface IService {} interface IEmailService : IService { Task SendAs
有人知道我在哪里可以找到 XML-RPC 接口(interface)的定义(在 OpenERP 7 中)?我想知道创建或获取对象需要哪些参数和对象属性。每个元素的 XML 示例也将非常有帮助。 最佳答
最近,我一直在阅读有关接口(interface)是抽象的错误概念的文章。一篇这样的帖子是http://blog.ploeh.dk/2010/12/02/InterfacesAreNotAbstract
如果我有一个由第三方实现的现有 IInterface 后代,并且我想添加辅助例程,Delphi 是否提供了任何简单的方法来实现此目的,而无需手动重定向每个接口(interface)方法?也就是说,给定
我正在尝试将 Article 数组分配给我的 Mongoose 文档,但 Typescript 似乎不喜欢这样,我不知道为什么它显示此警告/错误,表明它不可分配. 我的 Mongoose 模式和接口(
我有两个接口(interface): public interface IController { void doSomething(IEntity thing); } public inte
是否可以创建一个扩展 Serializable 接口(interface)的接口(interface)? 如果是,那么扩展接口(interface)的行为是否会像 Serilizable 接口(int
我试图在两个存储之间创建一个中间层,它从存储 A 中获取数据,将其转换为相应类型的存储 B,然后存储它。由于我需要转换大约 50-100 种类型,我希望使用 map[string]func 并根据 s
我正在处理一个要求,其中我收到一个 JSON 对象,其中包含一个日期值作为字符串。我的任务是将 Date 对象存储在数据库中。 这种东西: {"start_date": "2019-05-29", "
我们的方法的目标是为我们现有的 DAO 和模型类引入接口(interface)。模型类由各种类型的资源 ID 标识,资源 ID 不仅仅是随机数,还带有语义和行为。因此,我们必须用对象而不是原始类型来表
Collection 接口(interface)有多个方法。 List 接口(interface)扩展了 Collection 接口(interface)。它声明与 Collection 接口(int
我有一个 Java 服务器应用程序,它使用 Jackson 使用反射 API 对 DTO 进行一般序列化。例如对于这个 DTO 接口(interface): package com.acme.libr
如果我在 Kotlin 中有一个接口(interface): interface KotlinInterface { val id: String } 我可以这样实现: class MyCla
我知道Java中所有访问修饰符之间的区别。然而,有人问了我一个非常有趣的问题,我很难找到答案:Java 中的 private 接口(interface)和 public 接口(interface)有什
我是一名优秀的程序员,十分优秀!