为什么我输入断言一个接口时我的代码恐慌?

为什么我输入断言一个接口时我的代码恐慌?

问题描述:

我有一些服务器代码向端点发送请求并接收存储在类型为空接口的对象中的JSON响应。我必须解析出这些信息并将其存储在一个“Resource”对象中,Resource是一个接口。本例中的JSON数据表示一个“Position”对象,它满足Resource接口。所以基本上,这些代码是这样的:为什么我输入断言一个接口时我的代码恐慌?

// 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() 
} 

和位置模式是:

// 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) 

我的终点是设计来检索我的数据库位置的列表,所以这显然意味着,包含JSON数据的空接口包含一部分资源,并且无法将类型断言为切片(Go不允许这样做),而是通过迭代手动完成。所以我也跟着通过代码和孤立我的问题是:

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 
} 

一切都在上面的代码工作得很好,直到

ret[i] = rInterface.(Resource) 

,然后我的服务器炸毁和恐慌。我查看了Go文档,并且据我所知,即使rInterface是位置模型数据的空接口,因为Position类型仍然满足Resource接口,我应该能够输入assert到Resource中。我理解这一点是否正确?还是有我失踪的东西?

+0

恐慌说什么? – JimB

+0

当我发送获取请求时,我得到一个追溯到上面提到的代码行的堆栈跟踪,我得到一个500 – mudejar

+0

恐慌将包含一条错误消息,该消息是什么? – JimB

好Kaedys建议我换 R:= s.Index(I) 分为: R:= s.Index(I).Addr()

而且这并获得成功,显然问题在使用应该实现接口的对象时发生,但该对象上的所有方法都有指针接收器。我只需要将一个指向该类型的指针放入界面。