When doing "type X Y", is it a type alias or type redefinition or type adapter or something else?

115 views
Skip to first unread message

Sathish VJ

unread,
Aug 13, 2019, 12:53:20 AM8/13/19
to golang-nuts
And what is the difference between each of these: type alias, type redefinition, type adapter.

Volker Dobler

unread,
Aug 13, 2019, 1:49:51 AM8/13/19
to golang-nuts
type X Y declares a named type X with underlying type Y.
A type alias is something completely different (look up
"Alias declaration" in the Spec).

There are no such things like "type redefinition" or
"type adapter" in Go. See the Spec again: It contains
neither. So the main difference between a type alias and
the other two is: The other two do not exist.

V.

Sathish VJ

unread,
Aug 13, 2019, 2:10:56 AM8/13/19
to golang-nuts
So doing type X Y is just a type declaration then?

Meanwhile, I wrote a small example to help me figure out the differences between some of these based on the specs.  Leaving it here in case it is useful for somebody.

package main

import "fmt"

type X
struct {}
func
(X) f() {}

type Y X
// cannot call functions on X via Y

type Z
= X // alias declaration. identical types.

func main
() {
 x
:= X{}
 y
:= Y{}
 z
:= Z{}
 
 fmt
.Println(x, y, z)
 x
.f()
 z
.f()

 
// y.f() // not possible
}

Volker Dobler

unread,
Aug 13, 2019, 3:24:05 AM8/13/19
to golang-nuts
On Tuesday, 13 August 2019 08:10:56 UTC+2, Sathish VJ wrote:
So doing type X Y is just a type declaration then?

Yes, of course. It declares a new named type X, the underlying
type is Y which can be some predeclared type like int, some
other named declared type (like MyFooType) or a "type literal"
(a term I made up) like struct{X,Y float64; T string} or
map[string]bool or chan time.Time .

The main reason to declare a new type like
    type NewType SomeExistingType
is that NewType starts of with an empty method set and you
can implement totally different methods on it or even implement
the methods with the same name but with different signatures
and/or different semantics.

Type aliases are necessary e.g. during refactoring large code
bases or to provide a certain compatibility. Do not use them
in "regular" code as they do not provide any value but make
reading the code harder.

You might want to read more about "embedding" one type into
a struct type: Grep the Spec for "embedded field". Embedding
allows to have a new type with potentially different method set
but reuse methods of the embedded type.

V.

Jan Mercl

unread,
Aug 13, 2019, 3:43:05 AM8/13/19
to Volker Dobler, golang-nuts
On Tue, Aug 13, 2019 at 9:24 AM Volker Dobler
<dr.volke...@gmail.com> wrote:

> Yes, of course. It declares a new named type X, the underlying
> type is Y which can be some predeclared type like int, some
> other named declared type (like MyFooType) or a "type literal"
> (a term I made up) like struct{X,Y float64; T string} or
> map[string]bool or chan time.Time .

"Type literal" is not made up, it's a well defined part of the
specification: https://golang.org/ref/spec#TypeLit ;-)

Volker Dobler

unread,
Aug 13, 2019, 4:10:06 AM8/13/19
to golang-nuts
Thanks for pointing to the spec!
I actually did made it up while writing but was luck to choose
come up with the correct term; probably because I read it in the
spec some time ago ;-)

V.

Jesper Louis Andersen

unread,
Aug 13, 2019, 6:06:41 AM8/13/19
to Sathish VJ, golang-nuts
On Tue, Aug 13, 2019 at 8:10 AM Sathish VJ <sath...@gmail.com> wrote:
So doing type X Y is just a type declaration then?


In a certain sense

  type X Y

and

  type X = Y

are both type declarations. They differ in that the first is generative, whereas the other is a synonym. In a generative pattern, you are generating, or minting, a new type X which differs from Y; whereas in the the synonym situation, the types X and Y admits equality at the type level. Historically, Go only had generative types. The second case was added to the language, because of a need to facilitate large scale program rewriting. By aliasing a type, you can point an older implementation to a new one or vice versa, until the work has been completed. This avoids the need of one large patch across several modules, and allows for a more partial approach in which the programmer can split the patch over multiple commits.

As a simple example of why you would often prefer types to differ, consider something like

  type meter int
  type yard int

Clearly, you don't want to admit the interchange of two different distance units (Even worse: Pound-Force to Newton's). This is by far the common case in programming, and they are crucial for producing modular code via encapsulation and isolation.

jochen....@gmx.de

unread,
Aug 13, 2019, 11:03:36 AM8/13/19
to golang-nuts
type X Y is a type declaration, you have to cast between the types
type X=Y is a type alias, where X can be used as Y without casting

Volker Dobler

unread,
Aug 13, 2019, 3:14:10 PM8/13/19
to golang-nuts
On Tuesday, 13 August 2019 17:03:36 UTC+2, jochen...@gmx.de wrote:
type X Y is a type declaration, you have to cast between the types
type X=Y is a type alias, where X can be used as Y without casting

There are no type cast in Go. Only type conversions.

V.
Reply all
Reply to author
Forward
0 new messages