Interface method return other interface?

121 views
Skip to first unread message

Martin Palma

unread,
Oct 9, 2019, 3:39:30 AM10/9/19
to golang-nuts
I'm wondering If it is ok (or good Go code) if an interface method returns an other interface? Here an example:

type Querier interface {
 
Query() string
}

type
Decoder interface {
 
DecodeAndValidate() Querier
}


Mohamed Yousif

unread,
Oct 9, 2019, 4:01:52 AM10/9/19
to Martin Palma, golang-nuts
I always find accept interface and return struct to be very useful. It makes the code more cleaner. 



--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/531f29a6-ea2e-4416-a0d0-ce697dc7a09b%40googlegroups.com.

Jake Montgomery

unread,
Oct 9, 2019, 7:44:44 AM10/9/19
to golang-nuts
It is a generally accepted best practice in go to "accept interfaces and return structs". Just google "golang accept interfaces return structs". However, there are absolutely times when it is ok, or even necessary, to return an interface. They key to to read some of the articles about the practice to understand why the advice is given, so you can decide when it makes sense to go against it.

Axel Wagner

unread,
Oct 9, 2019, 7:48:23 PM10/9/19
to Martin Palma, golang-nuts
There's loads of precedence in the stdlib:

And don't forget that error itself is an interface.

Honestly, if you need it, go for it. There are definitely places where it's over abstraction to do it, but I don't think there's a good or universal rule you can use to decide which is which.

FWIW, I tend to disagree with the "return structs, accept interfaces" advise in general. If go had variant func/methods, that would be useful guidance. But as it stands, it is too often necessary to violate it (every usage of an error return value is in fact such a violation). And the "accept interfaces" part tends to lead to over abstraction (I would probably agree with "consider accepting interfaces if they already exist" though).

burak serdar

unread,
Oct 9, 2019, 8:58:29 PM10/9/19
to Axel Wagner, Martin Palma, golang-nuts
On Wed, Oct 9, 2019 at 5:48 PM 'Axel Wagner' via golang-nuts
<golan...@googlegroups.com> wrote:
>
> There's loads of precedence in the stdlib:
>
> https://godoc.org/net/http/#FileSystem.Open
> https://godoc.org/net/http#File.Stat
> https://godoc.org/net#Conn.LocalAddr
> https://godoc.org/database/sql/driver/#Driver.Open
> https://godoc.org/image#Image.ColorModel
> https://godoc.org/reflect/#Type.Elem
> And don't forget that error itself is an interface.
>
> Honestly, if you need it, go for it. There are definitely places where it's over abstraction to do it, but I don't think there's a good or universal rule you can use to decide which is which.
>
> FWIW, I tend to disagree with the "return structs, accept interfaces" advise in general. If go had variant func/methods, that would be useful guidance. But as it stands, it is too often necessary to violate it (every usage of an error return value is in fact such a violation). And the "accept interfaces" part tends to lead to over abstraction (I would probably agree with "consider accepting interfaces if they already exist" though).


There is one point you need to remember when returning interfaces:
make sure you handle nil correctly:

type S struct {}

type I interface {}

func f() *S {
return nil
}

func g() I {
x:=f()
return x
}

Above, g() is not nil. The correct code would be:

func g(() I {
x:=f()
if x==nil {
return nil
}
return x

}


>
> On Wed, Oct 9, 2019 at 9:39 AM Martin Palma <m...@palma.bz> wrote:
>>
>> I'm wondering If it is ok (or good Go code) if an interface method returns an other interface? Here an example:
>>
>> type Querier interface {
>> Query() string
>> }
>>
>> type Decoder interface {
>> DecodeAndValidate() Querier
>> }
>>
>>
>> --
>> You received this message because you are subscribed to the Google Groups "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
>> To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/531f29a6-ea2e-4416-a0d0-ce697dc7a09b%40googlegroups.com.
>
> --
> You received this message because you are subscribed to the Google Groups "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAEkBMfHHtn5t3TZOCG4xA_3kVbNqY2_xo7EtHoLyhi6P28ku9g%40mail.gmail.com.

Robert Engels

unread,
Oct 9, 2019, 9:12:31 PM10/9/19
to burak serdar, Axel Wagner, Martin Palma, golang-nuts
Ugh. Every time I see that I cringe....

> On Oct 9, 2019, at 7:58 PM, burak serdar <bse...@computer.org> wrote:
>
> On Wed, Oct 9, 2019 at 5:48 PM 'Axel Wagner' via golang-nuts
> To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqp-n0UaxQVpPVgJKayNzY6Voe5QRL4n7MoqmQMavL3oiQ%40mail.gmail.com.

Martin Palma

unread,
Oct 10, 2019, 3:14:12 AM10/10/19
to Robert Engels, burak serdar, Axel Wagner, golang-nuts
Thank you all for your feedback and input. Shame on me that I didn't
look hard enough through the stdlib for getting some examples, but
thanks Axel for pointing that out.
Reply all
Reply to author
Forward
0 new messages