Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Named and Unnamed Types

The problem:

I recently started reading the Golang Specification Manual and got stuck trying to understand the named and unnamed types in the relevant section. I come from a dynamic language and this has given me a bit of a headache.

The manual states:

A type determines the set of values and operations specific to values of that type. Types may be named or unnamed. Named types are specified by a (possibly qualified) type name; unnamed types are specified using a type literal, which composes a new type from existing types.

And continues:

Named instances of the boolean, numeric, and string types are predeclared. Composite types—array, struct, pointer, function, interface, slice, map, and channel types—may be constructed using type literals.

The problem here is that with the specification, the links make me jump around the pages and lose track of what is what with so many concepts thrown at me too fast.


Other Resources:

I have searched around for clarification on this and, other than the specification manual, resources are scarce. The only relevant material I could locate was:

  • Learning Go - Types - blog-post explaining nuances of the Type System in Go.

  • An issue here about pretty much the same thing I'm asking.

Unfortunately, I couldn't find any relevant questions on Stack Overflow regarding this. (and if they exist, I need to revise my search methods!). I'm asking because understanding the type system of a new language is one of the basic concepts in order to efficiently learn it.


So, the question:

Can somebody present a concise, clear example illustrating the differences between the concepts of named and unnamed types?*

*Additionally, explaining the concepts of qualified and pre-declared would be good for completeness but obviously not necessary.

like image 305
Dimitris Fasarakis Hilliard Avatar asked Oct 07 '15 03:10

Dimitris Fasarakis Hilliard


People also ask

What is underlying type in GO?

Each type T has an underlying type: If T is one of the predeclared boolean, numeric, or string types, or a type literal, the corresponding underlying type is T itself. Otherwise, T 's underlying type is the underlying type of the type to which T refers in its type declaration.

What are go types?

Go has three basic data types: bool: represents a boolean value and is either true or false. Numeric: represents integer types, floating point values, and complex types. string: represents a string value.


1 Answers

A simple way of thinking about it is that named types are those you define with the type statement, and unnamed types are composite types defined by a type literal.

For example, the type of the variable x is unnamed:

var x struct{ I int }

And the type of the variable y is named:

type Foo struct{ I int }
var y Foo

Each of these variables is considered to have a distinct type, even though the underlying type of each is the same (a structure containing a single integer member named I).

One property of unnamed types is that all variables declared using the same unnamed type are considered to have the same type, while two named types with the same underlying representation are distinct. For example:

var x2 struct{ I int }
type Bar struct{ I int }
var z Bar

Here x and x2 have the same type, while y and z do not.

These distinctions come into play in a few places in the language:

  1. Assigning a value of one named type to variable of a different named type is forbidden, even if the underlying type is the same. Assignment between related named and unamed types is allowed though. That is, the following are okay:

    x = y    // named type assigned to unnamed type
    y = x    // unnamed type assigned to named type
    

    But the following is an error:

    y = z    // assignment between different named types
    
  2. You can define methods for a type you've named. So adding methods to Foo is possible but there is no way you can attach methods to the variable x.

Note also that named types can be used in type literals to define new unnamed types. For example, the slice type []Foo is unnamed despite using Foo. If we wanted to attach methods to this slice type (e.g. for use with the sort package), we'd have to name it:

type Baz []Foo
like image 86
James Henstridge Avatar answered Sep 25 '22 08:09

James Henstridge