-1

I don't understand why the following code does not compile.

I am confused why Go is saying HistoryReader does not correctly implement IReader. HistoryBook implements IBook. Why are Read(book Ibook) and Read(book HistoryBook) not acceptable together when trying to add a HistoryReader to a slice of IReaders?

package main

type IReader interface {
   Read(book IBook)
}

// HistoryReader implements IReader
type HistoryReader struct{}

func (r *HistoryReader) Read(book HistoryBook) {
   // ...
}

type IBook interface{}

// HistoryBook implements IBook
type HistoryBook struct{}

func main() {
   var readerSlice []IReader

   _ = append(readerSlice, &HistoryReader{})
}
./main.go:28:26: cannot use &HistoryReader{} (value of type *HistoryReader) as type ReaderInterface in argument to append:
    *HistoryReader does not implement ReaderInterface (wrong type for Read method)
        have Read(book HistoryBook)
        want Read(book BookInterface)
mkrieger1
  • 19,194
  • 5
  • 54
  • 65
  • HistoryBook is not just IBook, It can be more than IBook. So instead of passing as HistoryBook, you can pass IBook and using 'cast type' inside the method. – Minh Dec 19 '22 at 02:31
  • 100% Duplicate. Asked each week. No contravariance in Go. – Volker Dec 19 '22 at 06:38

1 Answers1

6

IReader requires that Read takes any IBook.

But HistoryReader.Read only accepts a HistoryBook, not any IBook. Therefore, HistoryReader does not satisfy IReader.

mkrieger1
  • 19,194
  • 5
  • 54
  • 65