Dimitris Fasarakis Hilliard
Dimitris Fasarakis Hilliard

Reputation: 160377

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:

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.

Upvotes: 25

Views: 12353

Answers (2)

AndrewN
AndrewN

Reputation: 425

For starters, the Language Specification is what it sounds like -- a reference document. It's a great tool to use for reference, but not for learning about the language. you're better off learning about Go through the Go Tour, an interactive introduction to various aspects of the language or through Effective Go, which details how to use the language.

An unnamed type, is just a type declared without a name by using a type literal, in other words, the primitive type followed by a list of other types that make it inside {}. Or to quote the spec again, a type literal "composes a new type from existing types" An example with structs follows, but while unnamed struct might be rare, channels and maps (which again, do little on their own must be composed from other types) are rarely named.

package main

import "fmt"

type Named struct {
    x int
    y int
}

func main() {
    a := Named{1, 2}
    fmt.Println(a)

    b := struct{ x, y int }{1, 2}
    fmt.Println(b)
}

Upvotes: 1

James Henstridge
James Henstridge

Reputation: 43899

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

Upvotes: 38

Related Questions