1

Following is a snippet from one of the Go libs. Could anyone please point out the significance of r.(byteReader)? The syntax usage is not very obvious to a novice. byteReader is a defined interface and does not seem to be the member of io.Reader. Since, this seems to be some kind of nifty code, can anyone provide some insight.

The author mentions: "wrap it in a bufio.NewReader if it doesn't support ReadByte" pattern. https://github.com/dave-andersen/deltagolomb/blob/master/deltagolomb.go

type byteReader interface {
    io.Reader
    ReadByte() (c byte, err error)
}

func makeReader(r io.Reader) byteReader {
    if rr, ok := r.(byteReader); ok {
        return rr
    }
    return bufio.NewReader(r)
}
user31986
  • 1,558
  • 1
  • 14
  • 29
  • 1
    @Ainar-G They differ slightly in whether you assert to another interface (as in this case) or to a non-interface type (as in the other question) – ANisus Aug 31 '15 at 07:03

1 Answers1

6

r.(byteReader) is called a type assertion. Even if io.Reader doesn't implement the byteReader interface in itself, it it still possible that the value stored in r might implement byteReader. So, by doing the type assertion, you can assert if that is the case:

The specification states:

x.(T) asserts that x is not nil and that the value stored in x is of type T. The notation x.(T) is called a type assertion.
...
If T is an interface type, x.(T) asserts that the dynamic type of x implements the interface T.

Edit

The comment, "wrap it in a bufio.NewReader", refers to makeReader's provided io.Reader; if it doesn't implement byteReader, makeReader will wrap it in a bufio.Reader which does implement bytesReader, and return it instead.

ANisus
  • 74,460
  • 29
  • 162
  • 158