dqqxkq4047 2017-04-25 10:16
浏览 41
已采纳

附加到接口切片

I'm writing a document generator. There is a DocumentItem interface - this is part of the document.

type DocumentItem interface {
    compose() string
}

For example, a document consists of paragraphs and tables.

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

The Paragraph and Table types correspond to the DocumentItem interface.

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

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

The Document type contains the content []*DocumentItem field.

type Document struct {
    content []*DocumentItem
}

I'm looking for a way that would allow NewParagraph() and NewTable() functions to create the necessary data types and add them to the content field.

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
}

I use an slice of interface pointers in order to be able to modify the data in the corresponding variables after they are included in the document.

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

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

But I get compiler errors:

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

If I cast the types to an DocumentItem interface, I will lose access to specific functions, which in the case of one type may differ from the other. For example, add text to a paragraph and add a row of cells and then add text to cell for the table.

Is it possible at all?

Full example at https://play.golang.org/p/uJfKs5tJ98

  • 写回答

1条回答 默认 最新

  • dongwei3172 2017-04-25 10:19
    关注

    Don't use pointer to interface, only a slice of interfaces:

    content []DocumentItem
    

    If the dynamic value wrapped in the interface value is a pointer, you lose nothing, you will be able to modify the pointed object.

    This was the only thing that had to be changed. To verify, I added printing at the end:

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

    Output (try it on the Go Playground):

    &{text:lalala}
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 抖音咸鱼付款链接转码支付宝
  • ¥15 ubuntu22.04上安装ursim-3.15.8.106339遇到的问题
  • ¥15 求螺旋焊缝的图像处理
  • ¥15 blast算法(相关搜索:数据库)
  • ¥15 请问有人会紧聚焦相关的matlab知识嘛?
  • ¥15 网络通信安全解决方案
  • ¥50 yalmip+Gurobi
  • ¥20 win10修改放大文本以及缩放与布局后蓝屏无法正常进入桌面
  • ¥15 itunes恢复数据最后一步发生错误
  • ¥15 关于#windows#的问题:2024年5月15日的win11更新后资源管理器没有地址栏了顶部的地址栏和文件搜索都消失了