When do you recommend not using composition?

188 views
Skip to first unread message

Nitin Muppalaneni

unread,
Apr 28, 2023, 5:16:24 PM4/28/23
to golang-nuts
Is there a reason why `http.ResponseWriter` does not include io.Writer directly and instead has the `Write([]byte) (int, error)` method? Why did you choose to do it this way? I can see that it adds a dependency on the io package. Was that the concern?

And more generally, when would you recommend not using composition of interfaces?

Thanks
Nitin

Aaron Rubesh

unread,
Apr 28, 2023, 5:45:19 PM4/28/23
to golang-nuts
I would recommend reading up on how to implement Go interfaces.

The only requirement required to satisfy the io.Writer interface is a method Write([]byte)(int,error). If this method is present, Go can then interpret your struct as a io.Writer.

By itself, io.Writer provides no functionality only a definition. That is left to the struct to fulfill.

Nitin Muppalaneni

unread,
Apr 28, 2023, 6:09:19 PM4/28/23
to golang-nuts
I understand that interface does not provide the implementation. Perhaps my question was not clear. Let me try with the code snippets.

This is how http.ResponseWriter is written:
type http.ResponseWriter interface {
    ...
    Write([]byte) (int, error)
    ...
}

But it could have also been written this way:
type http.ResponseWriter interface {
    ...
    io.Writer
    ...
}

The second one uses embedding (https://go.dev/doc/effective_go#embedding), which I thought is preferable. I was curious why embedding was not used here and more broadly, when not to use embedding.

Thanks
Nitin

Ian Lance Taylor

unread,
Apr 28, 2023, 6:13:32 PM4/28/23
to Nitin Muppalaneni, golang-nuts
On Fri, Apr 28, 2023 at 3:09 PM Nitin Muppalaneni <muppa...@gmail.com> wrote:
>
> I understand that interface does not provide the implementation. Perhaps my question was not clear. Let me try with the code snippets.
>
> This is how http.ResponseWriter is written:
> type http.ResponseWriter interface {
> ...
> Write([]byte) (int, error)
> ...
> }
>
> But it could have also been written this way:
> type http.ResponseWriter interface {
> ...
> io.Writer
> ...
> }
>
> The second one uses embedding (https://go.dev/doc/effective_go#embedding), which I thought is preferable. I was curious why embedding was not used here and more broadly, when not to use embedding.

I don't know if this was the actual reason, but personally I think
listing the Write method explicitly makes the documentation easier to
read.

https://pkg.go.dev/net/http#ResponseWriter

Ian

Nitin Muppalaneni

unread,
Apr 28, 2023, 7:04:34 PM4/28/23
to golang-nuts
Thank you, Ian. It indeed makes documentation easier to read in this case. Unless the interface to be embedded is sufficiently self-documenting, as is the case with `heap.Interface` embedding `sort.Interface`, I will stick to listing the method[s] directly.


Thank you Aaron for the earlier reply.

Nitin
Reply all
Reply to author
Forward
0 new messages