【问题标题】:Append to slice of interfaces附加到接口切片
【发布时间】:2017-09-22 07:14:39
【问题描述】:

我正在编写一个文档生成器。有一个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 上的完整示例

【问题讨论】:

    标签: pointers go interface slice


    【解决方案1】:

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

    content []DocumentItem
    

    如果封装在接口值中的动态值是一个指针,你什么都不会丢失,你可以修改指向的对象。

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

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

    输出(在Go Playground 上试试):

    &{text:lalala}
    

    【讨论】:

      猜你喜欢
      • 2019-10-19
      • 1970-01-01
      • 2021-12-20
      • 2020-07-09
      • 1970-01-01
      • 2016-10-20
      • 2015-11-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多