简体   繁体   English

为什么当我输入 assert 接口时我的代码会发生恐慌?

[英]Why does my code panic when I type assert an interface?

I have some server code that sends a request to an endpoint and receives a JSON response which is stored in an object that is of type empty interface.我有一些服务器代码向端点发送请求并接收存储在空接口类型的对象中的 JSON 响应。 I have to parse out the information and store it in a slice of "Resource" objects, with Resource being an interface.我必须解析信息并将其存储在“资源”对象的切片中,资源是一个接口。 The JSON data in my case represents a "Position" object, which satisfies the Resource interface.在我的例子中,JSON 数据代表一个“Position”对象,它满足 Resource 接口。 So basically the code for these look like this:所以基本上这些代码看起来像这样:

// Resource interface type
type Resource interface {
    // Identifier returns the id for the object
    Identifier() bson.ObjectId
    // Description give a short description of the object
    Description() string
    // Initialize should configure a resource with defaults
    Initialize()
    // Collection name for resource
    Collection() string
    // Indexes for the resources
    Indexes() []mgo.Index
    // UserACL returns the user access control list
    UserACL() *UserACL
    // IsEqual should compare and return if resources are equal
    IsEqual(other Resource) bool
    // Refresh should update a resource from the database
    Refresh()
}

And the position model is:位置模型是:

// Position model
type Position struct {
    ID        bson.ObjectId `json:"id" bson:"_id,omitempty" fake:"bson_id"`
    Title     string        `json:"title" bson:"title" fake:"job_title"`
    Summary   string        `json:"summary" bson:"summary,omitempty" fake:"paragraph"`
    IsCurrent bool          `json:"isCurrent" bson:"is_current,omitempty" fake:"bool"`
    CompanyID bson.ObjectId `json:"company" bson:"company_id,omitempty" fake:"bson_id"`
    UACL      *UserACL      `bson:"user_acl,omitempty" fake:"user_acl"`
}

// Identifier returns the id for the object
func (p *Position) Identifier() bson.ObjectId {
    return p.ID
}

// Description give a short description of the object
func (p *Position) Description() string {
    return fmt.Sprintf("[%v:%v]", p.Collection(), p.ID)
}
....(the other methods follow)

My endpoint is designed to retrieve a list of positions in my database, so this obviously means that the empty interface containing the JSON data contains a slice of Resources, and can't be type asserted into a slice (Go doesn't allow this) and instead done manually by iteration.我的端点旨在检索我的数据库中的位置列表,因此这显然意味着包含 JSON 数据的空接口包含一个资源切片,并且不能将类型断言到切片中(Go 不允许这样做)而是通过迭代手动完成。 So I followed through the code and isolated my problem to this:所以我遵循了代码并将我的问题隔离为:

func InterfaceSlice(slice interface{}) []Resource {
    s := reflect.ValueOf(slice).Elem()
    if s.Kind() != reflect.Slice {
        panic("InterfaceSlice() given a non-slice type")
    }

    ret := make([]Resource, s.Len())

    for i := 0; i < s.Len(); i++ {
        r := s.Index(i)
        rInterface := r.Interface()
        ret[i] = rInterface.(Resource)
    }

    return ret
}

Everything in the above code is working just fine until上面代码中的所有内容都运行良好,直到

ret[i] = rInterface.(Resource)

and then my server blows up and panics.然后我的服务器炸毁和恐慌。 I looked through the Go documentation and as far as I can tell I should be able to type assert into Resource even though rInterface is an empty interface with Position model data because the Position type satisfies the Resource interface anyway.我查看了 Go 文档,据我所知,即使 rInterface 是一个带有 Position 模型数据的空接口,我也应该能够在 Resource 中输入 assert ,因为 Position 类型无论如何都满足 Resource 接口。 Am I correct in understanding this?我的理解正确吗? Or is there something I'm missing?或者有什么我想念的吗?

Ok Kaedys suggested that I change r := s.Index(i) Into: r := s.Index(i).Addr() Ok Kaedys 建议我将 r := s.Index(i) 改为: r := s.Index(i).Addr()

And this did the trick, apparently the problem occurs when you use an object that is supposed to fulfill an interface, but all the methods on that object have pointer receivers.这确实奏效了,显然当您使用一个应该实现接口的对象时会出现问题,但是该对象上的所有方法都有指针接收器。 I just needed to put a pointer to the type into the interface.我只需要在接口中放入一个指向类型的指针。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么 python 3 在我的代码中使用 test.json 时告诉我没有这样的文件或目录 - Why does python 3 tell me that there is no such file or directory when I use test.json in my code 在 Go 中将断言接口键入到 map 的更好方法 - Better way to type assert interface to map in Go 如何键入断言动态反射生成的结构接口 - How to type assert a dynamically reflection-generated struct interface 尝试进行API调用时,为什么我的python脚本停止执行? - Why does my python script stop executing when I try to make my API call? 为什么当我输入 node main.js 时我的 discord bot 没有上线? - Why doesn't my discord bot get online when I type node main.js? 合并我的代码后,为什么我的@JsonAlias无法正常工作? - Why does my @JsonAlias not work after merging my code? 为什么运行代码时为什么我的json数据不会出现在浏览器中 - Why my json data wont appear in browser when i run the code 为什么当我使用本地存储和 JSON 时我的代码不显示? - Why won't my code display when I use Local Storage and JSON? 颤振| 为什么当我尝试访问它时,我的 json 文件会转换为 firebase 上的文件夹? - Flutter | Why does my json file is transformed into a folder on firebase when I try to access it? 当我将googlesnippets ld + json添加到我的php页面时,为什么会出现错误? 503服务不可用 - Why does it give an error when I add googlesnippets ld + json to my php page? 503 Service Unavaible
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM