Go: Returning always nil error to implement interface

Issue

I have an interface:

type encoder interface {
    encode() ([]byte, error)
}

Some implementations of encoder return an error:

type fooEncoder string

func (e fooEncoder) encode() ([]byte, error) {
    if isSomeValidityCheck(e) {
        return []byte(e), nil
    }
    return nil, fmt.Errorf("Invalid type!")
}

But for others, there will never be an error:

type boolEncoder bool

func (e boolEncoder) encode() ([]byte, error) {
    if e {
        return []byte{0xff}, nil
    }
    return []byte{0x00}, nil
}

Is it idiomatic/correct to say a method will return an error, even if it will always be nil, so that it conforms to an interface? I have boolEncoder.encode returning an error only so that it conforms to encoder and can be used as such.

Solution

This is completely OK / normal. Often it’s more important to implement an interface than to reduce the code (of the method).

There are numerous examples in the standard lib too.

For example bytes/Buffer.Write() implements io.Writer with

func (b *Buffer) Write(p []byte) (n int, err error)

But writing to an in-memory buffer cannot fail, it documents that it never will return a non-nil error:

Write appends the contents of p to the buffer, growing the buffer as needed. The return value n is the length of p; err is always nil. If the buffer becomes too large, Write will panic with ErrTooLarge.

Buffer.Write() could have a signature that doesn’t return anything because its return values carry no information (n is always len(p) and err is always nil), but then you couldn’t use bytes.Buffer as an io.Writer, which is way more important.

See related: Is unnamed arguments a thing in Go? and Why does Go allow compilation of unused function parameters?

Answered By – icza

Answer Checked By – Marilyn (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.