创建一个接口,它是另一个接口的切片。

huangapple go评论74阅读模式
英文:

Create an interface that is a slice of another interface

问题

我想做类似以下的事情:

type Model interface {
    EntityType() string
    GetKey() *datastore.Key
    SetKey(*datastore.Key) error
    PreSave(context.Context) error
    PostSave(context.Context) error
    PostLoad(context.Context) error
}

type Models []Model

func (m Models) Prepare(num int) ([]Model, error) {
    // 进行 Models 切片的准备工作
}

这样,Models 结构体也是一个接口,并且会由实现 Model 接口的结构体切片来实现。类似以下的代码:

type Foo struct {
    key   *datastore.Key `datastore:"_"`
    // ... 其他字段
}

// 假设所有 Model 接口的函数都在这里并且有效

type Foos []Foo

func (f Foos) Prepare(num int) ([]Model, error) {
    // 进行 Foo 切片的准备工作
}

显然,上面的代码会抛出错误并且不可行。但是是否有一些代码可以产生基本相同的功能?而不使用 reflect 或其他昂贵的操作呢?

英文:

I'd like to do something like the following:

type Model interface {
	EntityType() string
	GetKey() *datastore.Key
	SetKey(*datastore.Key) error
	PreSave(context.Context) error
	PostSave(context.Context) error
	PostLoad(context.Context) error
}

type Models []Model interface {
	Prepare(int) ([]Model, error)
}

So that the struct Models is also an interface and would get implemented by a slice of the structs that implement Model. Something like the following:

type Foo struct {
    key   *datastore.Key `datastore:"_"`
    // ... other things here
}

// assume all Model interface funcs are here and valid

type Foos []Foo

func (f *Foos) Prepare (num int) ([]Model, error) {
    // do the preparations for Foo slice
}

Obviously, the code above throws errors and isn't possible. But is there some code that would produce basically the same functionality? Without using reflect or anything costly like that?

答案1

得分: 1

显然,一个简单的代码片段如下:

type Models interface {
    Prepare(int) ([]Model, error)
}

type Foos []Foo

func (f Foos) Prepare(num int) ([]Model, error) {
    // 对 Foo 切片进行准备工作
    return nil, nil
}

func main() {
    foos := Foos{}
    models := Models(foos)
    models.Prepare(17)
}

那么你的实际问题是什么?请参考 https://golang.org/doc/faq#covariant_typeshttps://golang.org/doc/faq#convert_slice_of_interface,这些链接可能会更清楚一些。

我建议提供操作 []Model 的函数(而不是方法),而不是将模型切片抽象为某个更高级的类型。

英文:

Obviously a simple

type Models interface {
    Prepare(int) ([]Model, error)
}
type Foos []Foo
func (f Foos) Prepare(num int) ([]Model, error) {
    // do the preparations for Foo slice
    return nil, nil
}
func main() {
    foos := Foos{}
    models := Models(foos)
    models.Prepare(17)
}

works.

So what is your actual question? Please see also https://golang.org/doc/faq#covariant_types and https://golang.org/doc/faq#convert_slice_of_interface
Which should make it a bit clearer.

I would recommend to provide function (! not methods) to operate on []Model and not to abstract the slice-of-model into some higher type.

huangapple
  • 本文由 发表于 2017年4月26日 15:08:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/43627252.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定