Types and Structures ==================== New Types --------- You can create your own types in Go_ using the ``type`` keyword. For example:: type Score int func show(s Score) { fmt.Println("mark =", s) } func main() { s := Score(5) // s is declared to be of type Score show(s) } In this example, ``int`` is said to be the **underlying type** of ``Score``. One reason to rename types in this way is to make your source code clearer. Another reason is that you can define methods on a type ``Score``, but you cannot define methods on a basic type such as ``int``. This sort of assignment is permitted:: show(5) Strictly speaking, 5 is an ``int``, and so it is *not* of type ``Score``. However, because ``Score`` has an underlying type of ``int``, this statement is not an error. Here is an example where you do get a type error. Suppose we add a new type called ``Mark``:: type Mark int And then call this code:: m := Mark(3) show(m) // compiler error: m is wrong type This doesn't compile because ``m`` is of type ``Mark``, but ``show`` expects a parameter of type ``Score``. Even though both ``Mark`` and ``Score`` have the same underlying type, one cannot be assigned to the other. See `the Go specification for the exact type equivalence rules `_. Structures ---------- Go_ structs are similar to the structures in C-like languages. For example, here is how you might represent a 2-dimensional point:: type Point struct { x, y int } One way to create a new struct is to use the ``new`` function like this:: p := new(Point) // new initializes p.x and p.y to their zero values fmt.Println("p.x: ", p.x) fmt.Println("p.y: ", p.y) The ``new`` function always sets the variables in a struct to their zero values. If you want to initialize them to some other values, you can use a composite literal like this:: dest := Point{-8, 11} // Point{-8, 11} is a composite literal fmt.Println("dest.x: ", dest.x) fmt.Println("dest.y: ", dest.y) Note that ``new`` is *not* written here. Here is an example of a struct built from two points:: type Segment struct { start, end Point } You can create a new ``Segment`` using a composite literal like this:: trip := Segment{Point{1, 2}, Point{3, 4}} fmt.Printf("%v\n", trip) // %v prints Go values in a nicely formatted way This prints:: {{1 2} {3 4}} Another way to write a composite literal is with explicit parameter names:: trip := Segment{start: Point{1, 2}, end: Point{3, 4}} When explicit names are given like this, the order of the parameters doesn't matter. The above declaration is the same as this:: trip := Segment{end: Point{3, 4}, start: Point{1, 2}} // order doesn't matter // when you provide // names Named composite literals are especially useful for longer, more complex structs where the order of parameters can be hard to remember.