Skip to content
This repository has been archived by the owner on Mar 22, 2021. It is now read-only.

Commit

Permalink
packages in the index and more comments from jc
Browse files Browse the repository at this point in the history
  • Loading branch information
miekg committed Aug 15, 2010
1 parent 3134bde commit 49b1085
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 73 deletions.
6 changes: 4 additions & 2 deletions go-basics.tex
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,8 @@ \section{Operators and built-in functions}
page \pageref{sec:panic} for more.

\paragraph{\func{print} and \func{println}} are low level printing
functions that can be used without reverting to the \package{fmt}
functions that can be used without reverting to the
\package{fmt}\index{Package!fmt}
package. These are mainly used for debugging.

\section{Go keywords}
Expand Down Expand Up @@ -671,7 +672,8 @@ \subsection{Slices}
\subsection{Maps}
\label{sec:maps}
Many other languages have a similar type built-in, Perl has hashes
Python has its dictionaries and C++ also has maps (in \package{lib}) for instance.
Python has its dictionaries and C++ also has maps (in
\package{lib}\index{Package!lib}) for instance.
In Go we have the
\type{map} type. A \type{map} can be thought of as an array indexed by
strings (in its most simple form).
Expand Down
92 changes: 40 additions & 52 deletions go-beyond.tex
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
\epi{\lstinline{fmt.Printf("\%p", i)}}{Printing the address of a pointer in Go.}
\noindent{}
You may have wished otherwise, but Go has pointers.
You may have wished otherwise, but Go does have pointers.
There is however no pointer arithmetic, so they act more like
references than pointers that you may know from C. Pointers as
they are still called in Go are useful.
Remember when you call a function in Go the variables you pass are
pass-by-value. So, for efficiency and the possibility to modify a
passed value \emph{in} the function we have pointers.
Remember that when you call a function in Go, the variables are
\emph{pass-by-value}. So, for efficiency and the possibility to modify a
passed value \emph{in} functions we have pointers.

Just like in C you declare a pointer by prefixing the type with an '*':
\lstinline{var p *int}. Now \var{p} is a pointer to an integer value.
Expand All @@ -32,7 +32,7 @@
type modifiers: \type{[]} declares something called an array slice; "*"
declares a pointer; \type{[size]} declares an array. So
\type{[]*[3]*int} is an array slice of pointers to arrays of three
pointers to \type{int}s.
pointers to \type{int}s.\todo{Make nice info graphic}

Dereferencing a pointer is done by prefixing the pointer variable with
"*":
Expand All @@ -51,22 +51,21 @@ \section{Allocation}
Go has garbage collection, meaning that you don't have to worry about
memory allocation and deallocation. Of course almost every language
since 1980 has this, but it is nice to see garbage collection in a
C-like language. The following sections show how to handle allocation
in Go. There is somewhat an artificial distinction between
\first{\key{new}}{Keywords!new} and \first{\key{make}}{Keywords!make}. Details follow.
C-like language which in not C++. The following sections show how to handle allocation
in Go. There is a somewhat an artificial distinction between
\first{\key{new}}{Keywords!new} and \first{\key{make}}{Keywords!make}.

\subsection{Allocation with new()}
\label{sec:allocation with new}
Go has two allocation primitives, \key{new} and \key{make}. They do different
things and apply to different types, which can be confusing, but the
rules are simple. Let's talk about \key{new} first. It's a built-in function
rules are simple. \key{new} is a built-in function
essentially the same as its namesakes in other languages: \func{new(T)}
allocates zeroed storage for a new item of type \type{T} and returns its
address, a value of type \type{*T}. In Go terminology, it returns a pointer to
a newly allocated zero value of type \type{T}.

Since the memory returned by \key{new} is zeroed, it's helpful to arrange
that the zeroed object can be used without further initialization. This
This
means a user of the data structure can create one with \key{new} and get
right to work. For example, the documentation for \func{bytes.Buffer} states
that "the zero value for Buffer is an empty buffer ready to use."
Expand Down Expand Up @@ -116,8 +115,9 @@ \subsection{Allocation with make()}
These examples illustrate the difference between \key{new()} and
\key{make()}.
\begin{lstlisting}
var p *[]int = new([]int) // allocates slice structure; *p == nil; rarely useful
var v []int = make([]int, 100) // v now refers to a new array of 100 ints
var p *[]int = new([]int) // allocates slice structure; *p == nil
// rarely useful
var v []int = make([]int, 100) // v refers to a new array of 100 ints

// Unnecessarily complex:
var p *[]int = new([]int)
Expand All @@ -132,7 +132,7 @@ \subsection{Allocation with make()}

\subsection{Constructors and composite literals}
Sometimes the zero value isn't good enough and an initializing
constructor is necessary, as in this example derived from package
constructor is necessary, as in this example taken from the package
\package{os}.
\begin{lstlisting}
func NewFile(fd int, name string) *File {
Expand Down Expand Up @@ -184,12 +184,13 @@ \subsection{Constructors and composite literals}

Composite literals can also be created for arrays, slices, and maps,
with the field labels being indices or map keys as appropriate. In these
examples, the initializations work regardless of the values of Enone,
Eio, and Einval, as long as they are distinct.
examples, the initializations work regardless of the values of
\var{Enone},
\var{Eio}, and \var{Einval}, as long as they are distinct.
\begin{lstlisting}
a := [...]string {Enone: "no error", Eio: "Eio", Einval: "invalid argument"}
s := []string {Enone: "no error", Eio: "Eio", Einval: "invalid argument"}
m := map[int]string{Enone: "no error", Eio: "Eio", Einval: "invalid argument"}
ar := [...]string {Enone: "no error", Eio: "Eio", Einval: "invalid argument"}
sl := []string {Enone: "no error", Eio: "Eio", Einval: "invalid argument"}
ma := map[int]string{Enone: "no error", Eio: "Eio", Einval: "invalid argument"}
\end{lstlisting}

\subsection{Conversions}
Expand Down Expand Up @@ -230,7 +231,7 @@ \section{Defining your own}
same way as in C, with the \key{struct} keyword.

An empty struct is created with \lstinline|var empty struct {}|.
A more real-life example would be when we want record somebodies name
A more real-life example would be when we want record somebody's name
and age in a single structure:

\lstinputlisting[label=src:struct,caption=Structures]{src/struct.go}
Expand All @@ -239,35 +240,21 @@ \section{Defining your own}
\begin{display}
{Pete, 42}
\end{display}
How nice is that, Go knows how to print your structure! If you
That is nice!
Go knows how to print your structure. If you
only want to print one, or a few, fields of the structure you'll
need to use \verb|.<field name>|. To only print the name:
need to use \verb|.<field name>|. For example to only print the name:
\begin{lstlisting}
fmt.Printf("%s", a.name) |\coderemark{\%s formats a string}|
\end{lstlisting}

Defining a new type:

\begin{lstlisting}
type T struct {
name string // name of the object
value int // its value
}
\end{lstlisting}

Or alias a build in one.
Methods on types, and methods on build in type -- can not do that,
just create a new type.

\section{Interfaces}
%%\epi{I have this phobia about having my body penetrated surgically. You
%%know what I mean?}{\textit{eXistenZ}\\\textsc{Ted Pikul}}
One of the interesting aspects of the Go language is \first{interface
objects}{interface objects}.
\gomarginpar{The following text is from \cite{go_interfaces}. Written by Ian
Lance Taylor --- one of the authors of Go.}
In Go, the word interface is overloaded to mean several different
things. Every type has an \first{interface}{interface}, which is the set of methods defined for
In Go, the word \first{interface}{interface} is overloaded to mean several different
things. Every type has an interface, which is the set of methods defined for
that type. This bit of code defines a struct type \type{S} with one field, and
defines two methods for \type{S}.
\begin{lstlisting}[caption=Defining a struct and methods on it,label=src:interface object]
Expand Down Expand Up @@ -300,15 +287,16 @@ \section{Interfaces}
\begin{lstlisting}
var s S; f(&s)
\end{lstlisting}
The reason we need to take the address of \type{S}, rather than a value of type
\type{S}, is because we defined the methods on \type{S} to operate on
The reason we need to take the address of \type{s}, rather than a value of type
\type{S}, is because we defined the methods on \type{s} to operate on
pointers, see the code above in listing \ref{src:interface object}.
This
is not a requirement --- we could have defined the methods to take
values --- but then the \func{Put} method would not work as expected.

The fact that you do not need to declare whether a type implements an
interface means that Go implements a form of \first{duck typing}{duck typing}.
The fact that you do not need to declare whether or not a type implements an
interface means that Go implements a form of
\first{duck typing}{duck typing}\cite{duck_typing}.
This is not
pure duck typing, because when possible the Go compiler will statically
check whether the type implements the interface. However, Go does have a
Expand Down Expand Up @@ -389,12 +377,12 @@ \section{Interface names}
meaning as a method on a well-known type, give it the same name and
signature; call your string-converter method \func{String} not
\func{ToString}.
from \cite{effective_go}.

\gomarginpar{Text copied from \cite{effective_go}.}

\section{Introspection}
A \key{switch} can also be used to discover the dynamic type of an interface
variable. Such a type switch\gomarginindex{\emph{type switch}}{type switch} uses
In a program, you can discover the dynamic type of an interfave variable
by using a \key{switch}.
Such a type switch\gomarginindex{\emph{type switch}}{type switch} uses
the syntax of a type assertion with the keyword type inside the
parentheses. If the switch declares a variable in the expression, the
variable will have the corresponding type in each clause.
Expand All @@ -421,7 +409,7 @@ \section{Introspection}
func WhichOne(x interface{}) { |\longremark{This function must accept \emph{both} %
types as valid input, so we use the empty Interface, which every type implements;}|
switch t := x.(type) { |\longremark{The type switch: \texttt{(type)};}|
case *PersonAge: |\longremark{When allocated with \func{new} its a %
case *PersonAge: |\longremark{When allocated with \func{new} it's a %
pointer. So we check for \type{*PersonAge}. If \func{WhichOne()} was %
called with a non pointer value, we should check for \type{PersonAge}.}|
println("Age person")
Expand All @@ -436,8 +424,6 @@ \section{Introspection}
time checking for more (built-in) types:
\begin{lstlisting}[caption=A more generic type switch]
switch t := interfaceValue.(type) { |\coderemark{The type switch}|
default:
fmt.Printf("unexpected type %T", t) // \%T prints type
case bool:
fmt.Printf("boolean %t\n", t)
case int:
Expand All @@ -446,15 +432,17 @@ \section{Introspection}
fmt.Printf("pointer to boolean %t\n", *t)
case *int:
fmt.Printf("pointer to integer %d\n", *t)
default:
fmt.Printf("unexpected type %T", t) // \%T prints type
}
\end{lstlisting}

\subsection{Introspection and reflection}
\label{subsec:introspection and reflection}
In the following example we want to look at the "tag" (here named
"namestr") defined in the
type definition of \type{Person}. We are using the
\package{reflect} package (there is no other way in Go). Keep in mind
type definition of \type{Person}. To do this we need the
\package{reflect}\index{Package!reflect} package (there is no other way in Go). Keep in mind
that looking at a tag means going back the \emph{type} definition. So
use the \package{reflect} we need figure out the type of the variable
and then access the tag.
Expand Down
7 changes: 4 additions & 3 deletions go-communication.tex
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ \section{Files}
Reading from (and writing to) files is easy in Go. This program
only uses the \package{os} package to read data from the file \file{/etc/passwd}.
\lstinputlisting[numbers=right,caption=Reading from a file (unbufferd),label=src:read]{src/file.go}
If you want to use \first{buffered}{buffered} IO there is the \package{bufio} package:
If you want to use \first{buffered}{buffered} IO there is the
\package{bufio}\index{Package!bufio} package:
%%\lstinputlisting[numbers=right,caption=Reading from a file (bufferd),label=src:bufread]{src/buffile.go}

On line 12 we create a \type{bufio.Reader} from \var{f} which is of
Expand All @@ -30,7 +31,7 @@ \section{Files}
the \type{*File} indeed does so.

\section{Executing commands}
The \package{exec} package has function to run external commands, and it the premier way to
The \package{exec}\index{Package!exec} package has function to run external commands, and it the premier way to
execute commands from within a Go program. We start commands with
the \func{Run} function:
\begin{lstlisting}
Expand All @@ -47,7 +48,7 @@ \section{Executing commands}

cmd, err := exec.Run("/bin/ls", []string{"ls", "-l"}, nil, "", exec.DevNull, exec.DevNull, exec.DevNull})
\end{lstlisting}
In the \package{os} package we find the \func{ForkExec} function. This
In the \package{os}\index{Package!os} package we find the \func{ForkExec} function. This
is another way (but more low level) to start executables.\footnote{There is talk on
the Gonuts mailing list about separating \func{Fork} and
\func{Exec}.}
Expand Down
37 changes: 21 additions & 16 deletions go-packages.tex
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
\first{\key{package}}{Keywords!package} keyword. Note that (at least one of) the filename(s) should
match the package name. Go packages may consist out of multiple files,
but they share the \lstinline{package <name>} line.
Lets define our package \package{even} in the file \prog{even.go}.
Lets define our package \package{even}\index{Package!even} in the file \prog{even.go}.

\lstinputlisting[label=src:even,caption=A small package]{src/even.go}
Names that start with a capital letter are exported and may be used
Expand Down Expand Up @@ -108,7 +108,7 @@ \section{Identifiers}

\subsection{Package names}
When a package is imported (with \first{\key{import}}{Keywords!import}, the package name becomes
an accessor for the contents. After
an accessor for the contents. After\index{Package!bytes}
\begin{lstlisting}
import "bytes"
\end{lstlisting}
Expand All @@ -131,19 +131,22 @@ \subsection{Package names}
Another convention is that the package name is the base name of its
source directory; the package in \package{src/pkg/container/vector} is imported as
"container/vector" but has name vector, not container\_vector and not
containerVector.
containerVector.\index{Package!container/vector}

The importer of a package will use the name to refer to its contents, so
exported names in the package can use that fact to avoid
stutter. For instance, the buffered reader type in the \package{bufio} package is
stutter. For instance, the buffered reader type in the
\package{bufio}\index{Package!bufio}
package is
called \func{Reader}, not \func{BufReader}, because users see it as
\func{bufio.Reader},
which is a clear, concise name. Moreover, because imported entities are
always addressed with their package name, \func{bufio.Reader} does not conflict
with \func{io.Reader}. Similarly, the function to make new instances of
\func{ring.Ring}---which is the definition of a constructor in Go---would normally
be called \func{NewRing}, but since \type{Ring} is the only type exported by the
package, and since the package is called \package{ring}, it's called
package, and since the package is called
\package{ring}\index{Package!ring}, it's called
just \func{New}.
Clients of the package see that as \func{ring.New}. Use the package structure
to help you choose good names.
Expand Down Expand Up @@ -302,17 +305,19 @@ \section{Useful packages}
a worth a mention:

\begin{description}
\item[\package{fmt}]{...}
\item[\package{io}]{...}
\item[\package{strconv}]{...}
\item[\package{os}]{...}
\item[\package{flag}]{...}
\item[\package{json}]{...}
\item[\package{template}]{...}
\item[\package{http}]{...}
\item[\package{unsafe}]{...}
\item[\package{reflect}]{...}
\item[\package{exec}]{...}
\item[\package{fmt}]{\index{Package!fmt}...}
\item[\package{io}]{\index{Package!io}...}
\item[\package{bufio}]{\index{Package!bufio}...}
\item[\package{sort}]{\index{Package!sort}...}
\item[\package{strconv}]{\index{Package!strconv}...}
\item[\package{os}]{\index{Package!os}...}
\item[\package{flag}]{\index{Package!flag}...}
\item[\package{json}]{\index{Package!json}...}
\item[\package{template}]{\index{Package!template}...}
\item[\package{http}]{\index{Package!http}...}
\item[\package{unsafe}]{\index{Package!unsafe}...}
\item[\package{reflect}]{\index{Package!reflect}...}
\item[\package{exec}]{\index{Package!exec}...}
\end{description}

\section{Exercises}
Expand Down
6 changes: 6 additions & 0 deletions go.bib
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ @misc{csp
title = "Communicating sequential processes"
}

@misc{duck_typing,
author = "Wikipedia",
howpublished = {\url{http://en.wikipedia.org/wiki/Duck_typing}},
title = "Duck typing"
}

@misc{bubblesort,
author = "Wikipedia",
howpublished = {\url{http://en.wikipedia.org/wiki/Bubble_sort}},
Expand Down

0 comments on commit 49b1085

Please sign in to comment.