附加到接口切片

时间:2017-04-25 10:16:11

标签: pointers go interface slice

我正在编写文档生成器。有一个DocumentItem接口 - 这是文档的一部分。

type DocumentItem interface {
    compose() string
}

例如,文档由段落和表格组成。

type Paragraph struct {
    text string
}
type Table struct{}

ParagraphTable类型对应DocumentItem界面。

func (p *Paragraph) compose() string {
    return ""
}

func (t *Table) compose() string {
    return ""
}

Document类型包含content []*DocumentItem字段。

type Document struct {
    content []*DocumentItem
}

我正在寻找一种方法,允许NewParagraph()NewTable()函数创建必要的数据类型并将其添加到content字段。

func (d *Document) NewParagraph() *Paragraph {
    p := Paragraph{}
    d.content = append(d.content, &p)
    return &p
}

func (d *Document) NewTable() *Table {
    t := Table{}
    d.content = append(d.content, &t)
    return &t
}

我使用一片接口指针,以便能够在文档中包含相应变量后修改它们。

func (p *Paragraph) SetText(text string) {
    p.text = text
}

func main() {
    d := Document{}
    p := d.NewParagraph()
    p.SetText("lalala")
    t := d.NewTable()
    // ...    
}

但是我遇到了编译器错误:

cannot use &p (type *Paragraph) as type *DocumentItem in append
cannot use &t (type *Table) as type *DocumentItem in append

如果我将类型转换为DocumentItem接口,我将失去对特定功能的访问权限,在一种类型的情况下,可能会有不同的功能。例如,将文本添加到段落并添加一行单元格,然后将文本添加到表格的单元格中。

有可能吗?

https://play.golang.org/p/uJfKs5tJ98

的完整示例

1 个答案:

答案 0 :(得分:4)

不要使用指向接口的指针,只使用一片接口:

content []DocumentItem

如果包含在接口值中的动态值是指针,则不会丢失任何内容,您将能够修改指向的对象。

这是唯一需要改变的事情。为了验证,我在最后添加了打印:

fmt.Printf("%+v", p)

输出(在Go Playground上尝试):

&{text:lalala}