我正在编写文档生成器。有一个DocumentItem
接口 - 这是文档的一部分。
type DocumentItem interface {
compose() string
}
例如,文档由段落和表格组成。
type Paragraph struct {
text string
}
type Table struct{}
Paragraph
和Table
类型对应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
接口,我将失去对特定功能的访问权限,在一种类型的情况下,可能会有不同的功能。例如,将文本添加到段落并添加一行单元格,然后将文本添加到表格的单元格中。
有可能吗?
的完整示例答案 0 :(得分:4)
不要使用指向接口的指针,只使用一片接口:
content []DocumentItem
如果包含在接口值中的动态值是指针,则不会丢失任何内容,您将能够修改指向的对象。
这是唯一需要改变的事情。为了验证,我在最后添加了打印:
fmt.Printf("%+v", p)
输出(在Go Playground上尝试):
&{text:lalala}