Interface definition as type alias

723 views
Skip to first unread message

Javier Zunzunegui

unread,
Sep 8, 2020, 4:13:23 AM9/8/20
to golang-nuts
TLDR: Why should I NOT the alias form `type ... = interface {...}` instead of the standard `type ... interface {...}` for interface declarations?

The extended question:

The normal type definition for an interface in go would be `type TypeName interface {...}`. This results in a new type, which is assignable to other types of the similar interfacce, such that this is valid:
```
type I1 interface{ Foo() }
type I2 interface{ Foo() }
var _ I1 = I2(nil)
```
But these are different types, such that any function with one of these in the signature can't be converted to a similar function with the other, such that this is NOT valid:
```
var _ func(I1) = (func(I2))(nil)
```

Declare the types as aliases however, and the limitation dissapears:
```
type I1 interface{ Foo() }
type I2 interface{ Foo() }
var _ I1 = I2(nil) // still valid
var _ func(I1) = (func(I2))(nil) // now valid
```

A runnable example of the below using `http.ResponseWriter`:
My point being using aliases offers an advantage (more flexible assignment and interface implementation) and to my knowledge no meaningful drawback. So why not use it everywhere?

Volker Dobler

unread,
Sep 8, 2020, 5:41:25 AM9/8/20
to golang-nuts
In practice you never declare the same interface twice 
switch from one to the other. Why would anybody declare
his own ResonseWriter interface if net/http.ResponseWriter
exists?

So yes: Using a type alias has advantages, but no, this
advantage is never realized because neither the alias nor
the plain type decl are used in practice.

V.

Axel Wagner

unread,
Sep 8, 2020, 6:06:44 AM9/8/20
to Javier Zunzunegui, golang-nuts
The only real downsides, I think, are that compiler errors gets harder to read:
And likewise, that the name won't appear at runtime, so if you print things using `reflect`, the result will be less readable.

I think there are cases where it has advantages, such as breaking import cycles. They probably can be solved in other ways too, though.

IMO, if the conclusion would be "always use type-aliases", I'd prefer "Go should make parameters and returns contra- and covariant respectively". Because we'd essentially saying that interfaces should be represented by their method set, not their type-name:
Which is a fine position to take, but full contra- and covariance is both cleaner and more powerful - again, IMHO.

--
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/d9595614-ce72-4602-8ead-67e9a1427181n%40googlegroups.com.

Javier Zunzunegui

unread,
Sep 8, 2020, 6:15:42 AM9/8/20
to golang-nuts
> So yes: Using a type alias has advantages, but no, this advantage is never realized because neither the alias nor the plain type decl are used in practice.

The ResonseWriter is a bad example because it has a method `Header() http.Header`, for which you must import net/http regardless. 
Take fmt.Stringer, `type Stringer interface { String() string }`. I could perfectly well define `type MyStringer interface { String() string }` and use that instead of fmt.Stringer (if fmt.Stringer were an alias, with much more flexibility), and avoid importing fmt altogether. And even this scenario is trivial (I have nothing agaist importing fmt!), but for my own interfaces having the interface defined in separate places can help avoid import cycles, make packages more locally contained, keep compilation faster, etc.

Hence why I'm asking for reasons against it. I have used this before and it has served me well, so I know there are advantages.

Javier Zunzunegui

unread,
Sep 8, 2020, 6:26:00 AM9/8/20
to golang-nuts
> The only real downsides, I think, are that compiler errors gets harder to read:
> And likewise, that the name won't appear at runtime, so if you print things using `reflect`, the result will be less readable.

Yeah, those are the downsides I am familiar with. The reflect I have no issue with, the compiler errors is a bit more unfortunate. I wasn't aware of those proposals, though looking at their dates they are not being actively considered.

Does it have performance implications? Is there any difference in type resolution for typed interfaces vs untyped ones?
Reply all
Reply to author
Forward
0 new messages