Go proverb says “Accept interfaces, return structs”. I want to decouple novelapp package (the consumer) from the package novel (the provider) and use novel without importing via an interface. This works for Book interface with title function but I cannot substitute Page for PageInterface… why not?
what I wanted to achieve is to be able to drop in any package almost independent of each other and use main to glue the parts together.
Example Code:
// package novel
package novel
// Page ...
type Page struct {
title string
}
func NewPage(title string) Page {
return Page{title: title}
}
// Title ...
func (p *Page) Title() string {
return p.title
}
// Book ...
type Book struct {
title string
pages []Page
}
func NewBook(title string, pages []Page) *Book {
return &Book{title: title, pages: pages}
}
// Title ...
func (b *Book) Title() string {
return b.title
}
// Pages ...
func (b *Book) Pages() []Page {
return b.pages
}
// package novelapp
package novelapp
import "fmt"
// BookInterface ...
type BookInterface interface {
Title() string
Pages() []PageInterface
}
// PageInterface ...
type PageInterface interface {
Title() string
}
// PrintBook ...
func PrintBook(book BookInterface) {
fmt.Println(book.Title())
}
// package main
package main
import (
"sandbox/pkg/novel"
"sandbox/pkg/novelapp"
)
func main() {
book := novel.NewBook("Book Title", []novel.Page{novel.NewPage("Page Title")})
novelapp.PrintBook(book)
}
.\main.go:10:20: cannot use book (type *novel.Book) as type novelapp.BookInterface in argument to novelapp.PrintBook:
*novel.Book does not implement novelapp.BookInterface (wrong type for Pages method)
have Pages() []novel.Page
want Pages() []novelapp.PageInterface