2016-10-18 110 views
-2

我有一些服務器代碼向端點發送請求並接收存儲在類型爲空接口的對象中的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

回答

0

好Kaedys建議我換 R:= s.Index(I) 分爲: R:= s.Index(I).Addr()

而且這並獲得成功,顯然問題在使用應該實現接口的對象時發生,但該對象上的所有方法都有指針接收器。我只需要將一個指向該類型的指針放入界面。