golang:它的结构片!=它实现的接口片? [英] golang: slice of struct != slice of interface it implements?

查看:115
本文介绍了golang:它的结构片!=它实现的接口片?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个接口 Model ,它由struct Person

实现。

为了得到一个模型实例,我有以下的帮助函数:

  func newModel(c string)模型{
switch c {
caseperson:
return newPerson()
}
return nil
}

func newPerson()* Person {
return& Person {}
}

上面的方法允许我返回一个正确类型的Person实例(以后可以用相同的方法轻松添加新的模型)。

当我尝试做类似的事情来返回一个一片模型,我得到一个错误。代码:

  func newModels(c string)[]模型{
switch c {
caseperson :
return newPersons()
}
return nil
}

func newPersons()* [] Person {
var models [ ]人们抱怨:<
return& models
}

c $ c>不能使用newPersons()(type [] Person)作为类型[]返回参数中的模型



我的目标是返回无论是 [] Person , [] FutureModel [] Terminator2000 ,w / e)。我错过了什么,以及如何正确实施这样的解决方案? 解决方案

这与我刚刚回答的问题非常相似: https://stackoverflow.com/a/12990540/727643



简短的回答是你是对的。一片结构不等于结构实现的一个接口片。



A [] Person 和一个 []模型具有不同的内存布局。这是因为他们切片的类型具有不同的内存布局。一个模型是一个接口值,这意味着在内存中它是两个字的大小。一个字为类型信息,另一个为数据。一个 Person 是一个结构,它的大小取决于它包含的字段。为了从 [] Person 转换为 [] Model ,您需要遍历数组并为每个元素做一个类型转换。

由于这个转换是一个O(n)操作,并且会导致创建一个新的片,所以Go拒绝隐式执行。你可以使用下面的代码显式地完成它。

  models:= make([] Model,len(persons))
for i,v:= range persons {
models [i] = Model(v)
}
返回模型

正如 dskinner指出的,您很可能需要一个切片的指针而不是指向片的指针。

  * [] Person //指向切片的指针
[] * Person //指针


I have an interface Model, which is implemented by struct Person.

To get a model instance, I have the following helper functions:

func newModel(c string) Model {
    switch c {
    case "person":
        return newPerson()
    }
    return nil
}

func newPerson() *Person {
    return &Person{}
}

The above approach allows me to return a properly typed Person instance (can easily add new models later with same approach).

When I attempted to do something similar for returning a slice of models, I get an error. Code:

func newModels(c string) []Model {
    switch c {
    case "person":
        return newPersons()
    }
    return nil
}

func newPersons() *[]Person {
    var models []Person
    return &models
}

Go complains with: cannot use newPersons() (type []Person) as type []Model in return argument

My goal is to return a slice of whatever model type is requested (whether []Person, []FutureModel, []Terminator2000, w/e). What am I missing, and how can I properly implement such a solution?

解决方案

This is very similar to a question I just answered: https://stackoverflow.com/a/12990540/727643

The short answer is that you are correct. A slice of structs is not equal to a slice of an interface the struct implements.

A []Person and a []Model have different memory layouts. This is because the types they are slices of have different memory layouts. A Model is an interface value which means that in memory it is two words in size. One word for the type information, the other for the data. A Person is a struct whose size depends on the fields it contains. In order to convert from a []Person to a []Model, you will need to loop over the array and do a type conversion for each element.

Since this conversion is an O(n) operation and would result in a new slice being created, Go refuses to do it implicitly. You can do it explicitly with the following code.

models := make([]Model, len(persons))
for i, v := range persons {
    models[i] = Model(v)
}
return models

And as dskinner pointed out, you most likely want a slice of pointers and not a pointer to a slice. A pointer to a slice is not normally needed.

*[]Person        // pointer to slice
[]*Person        // slice of pointers

这篇关于golang:它的结构片!=它实现的接口片?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆