2017-04-25 67 views
1

我正在寫一個文檔生成器。有一個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

回答

4

完整的示例,不要使用指針接口,只有一個切片接口:

content []DocumentItem 

如果包裹在接口值動態值是一個指針,你失去什麼,您將能夠修改尖銳的對象。

這是唯一需要改變的東西。爲了驗證,我在結尾加上印刷:

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

輸出(嘗試在Go Playground):

&{text:lalala}