blob: 5152905a2b107506a7e8707b658702d12bf76e7c [file] [log] [blame]
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
<title>A Tour of Go</title>
<!-- jQuery -->
<script src="static/jquery.js"></script>
<!-- Fonts -->
<link href='http://fonts.googleapis.com/css?family=Droid+Serif&v1' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Droid+Sans&v1' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Droid+Sans+Mono&v1' rel='stylesheet' type='text/css'>
<!-- Playground -->
<link rel="stylesheet" href="/static/codemirror/lib/codemirror.css">
<script src="/static/codemirror/lib/codemirror.js"></script>
<link rel="stylesheet" href="/static/codemirror/theme/default.css">
<script src="static/playground.js"></script>
<!-- Tour -->
<link rel="stylesheet" href="static/tour.css" charset="utf-8">
<script src="static/mode.js"></script>
<script src="static/tour.js"></script>
</head>
<body class="loading">
<!-- Top bar -->
<h2 id="slidenum"></h2>
<div id="topnav" class="nav">
<button id="tocbtn">INDEX</button>
</div>
<h1>A Tour of Go</h1>
<!-- Loading message -->
<div id="loading">
Loading slides...
</div>
<!-- Table of Contents -->
<ol id="toc"></ol>
<div id="slides" class="slides"><!-- begin slides -->
<div class="toc">Welcome</div>
<div class="slide">
<h2>Hello, 世界</h2>
<p>
Welcome to a tour of the
<a target="_blank" href="http://golang.org/">Go programming language</a>.
<p>
The tour is divided into three sections. At the end of each section
is a series of exercises for you to complete.
<p>
The tour is interactive. Click the Run button now (or type
Shift-Enter) to compile and run the program on
<span class="appengineMode">a remote server.</span>
<span class="localMode">your computer.</span>
The result is displayed below the code.
<p>
These example programs demonstrate different aspects of Go. The
programs in the tour are meant to be starting points for your own
experimentation.
<p>
Edit the program and run it again.
<p>
Whenever you're ready to move on, click the Next button or type the
PageDown key.
<div>
package main
import "fmt"
func main() {
fmt.Println("Hello, 世界")
}
</div>
</div>
<div class="slide nocode appengineMode">
<h2>Go offline</h2>
<p>
This tour is also available as a stand-alone program that you can use
without access to the internet.
<p>
The stand-alone tour is faster, as it builds and runs the code samples
on your own machine. It also includes additional exercises not
available in this sandboxed version.
<p>
To run the tour locally first
<a target="_blank" href="http://golang.org/doc/install.html">install Go</a> (the latest stable release, <code>release.r60</code>),
then use
<a target="_blank" href="http://golang.org/cmd/goinstall/">goinstall</a>
to install
<a target="_blank" href="http://code.google.com/p/go-tour/">gotour</a>:
<pre> goinstall go-tour.googlecode.com/hg/gotour</pre>
<p>
and run the resultant <code>gotour</code> executable.
<p>
Otherwise, click the "next" button or type PageDown to continue.
<p>
<i>(You may return to these instructions at any time by clicking the
"index" button.)</i>
</div>
<div class="slide nocode appengineMode">
<h2>Go local</h2>
<p>
The tour is available in other languages:
<ul>
<li><a href="http://go-tour-zh.appspot.com/">Chinese &mdash; 中文</a></li>
<li><a href="http://go-tour-jp.appspot.com/">Japanese &mdash; 日本語</a></li>
<li><a href="http://go-tour-kr.appspot.com/">Korean &mdash; 한국어</a></li>
</ul>
<p>
(If you would like to translate the tour to another language, check
out the source from <code>https://go-tour.googlecode.com/hg</code>,
translate <code>static/index.html</code>, and then deploy it to App
Engine using the instructions in <code>appengine/README</code>.)
<p>
Click the "next" button or type PageDown to continue.
</div>
<div class="toc">Introduction</div>
<div class="slide">
<h2>Packages</h2>
<p>
Every Go program is made up of packages.
<p>
Programs start running in package <code>main</code>.
<p>
This program is using the packages with import paths
<code>"fmt"</code> and <code>"math"</code>.
<p>
By convention, the package name is the same as the
last element of the import path.
<div>
package main
import (
"fmt"
"math"
)
func main() {
fmt.Println("Happy", math.Pi, "Day")
}
</div>
</div>
<div class="slide">
<h2>Imports</h2>
<p>
This code groups the imports into a parenthesized, "factored" import
statement. You can also write multiple import statements, like:
<pre>
import "fmt"
import "math"
</pre>
but it's common to use the factored form to eliminate clutter.
<div>
package main
import (
"fmt"
"math"
)
func main() {
fmt.Printf("Now you have %g problems.",
math.Nextafter(2, 3))
}
</div>
</div>
<div class="slide">
<h2>Exported names</h2>
<p>
After importing a package, you can refer to the names it exports.
<p>
In Go, a name is exported if it begins with a capital letter.
<p>
<code>Foo</code> is an exported name, as is <code>FOO</code>.
The name <code>foo</code> is not exported.
<p>
Run the code. Then rename <code>math.pi</code> to <code>math.Pi</code>
and try it again.
<div>
package main
import (
"fmt"
"math"
)
func main() {
fmt.Println(math.pi)
}
</div>
</div>
<div class="slide">
<h2>Functions</h2>
<p>
A function can take zero or more arguments.
<p>
In this example, <code>add</code> takes two parameters of type <code>int</code>.
<p>
Notice that the type comes <i>after</i> the variable name.
<p>
(For more about why types look the way they do, see <a target="_blank" href="http://blog.golang.org/2010/07/gos-declaration-syntax.html">this blog post</a>.)
<div>
package main
import "fmt"
func add(x int, y int) int {
return x + y
}
func main() {
fmt.Println(add(42, 13))
}
</div>
</div>
<div class="slide">
<h2>Functions</h2>
<p>
When two or more consecutive named function parameters share a type,
you can omit the type from all but the last.
<p>
In this example, we shortened
<pre>x int, y int</pre>
<p>
to
<pre>x, y int</pre>
<div>
package main
import "fmt"
func add(x, y int) int {
return x + y
}
func main() {
fmt.Println(add(42, 13))
}
</div>
</div>
<div class="slide">
<h2>Functions</h2>
<p>
A function can return any number of results.
<p>
This function returns two strings.
<div>
package main
import "fmt"
func swap(x, y string) (string, string) {
return y, x
}
func main() {
a, b := swap("hello", "world")
fmt.Println(a, b)
}
</div>
</div>
<div class="slide">
<h2>Functions</h2>
<p>
Functions take parameters; in Go results can be named and act like
variables; these are called "result parameters."
<p>
If the result parameters are named, a <code>return</code> statement
without arguments returns the current values of the results.
<div>
package main
import "fmt"
func split(sum int) (x, y int) {
x = sum * 4/9
y = sum - x
return
}
func main() {
fmt.Println(split(17))
}
</div>
</div>
<div class="slide">
<h2>Variables</h2>
<p>
The <code>var</code> statement declares a list of variables;
as in function argument lists, the type is last.
<div>
package main
import "fmt"
var x, y, z int
var c, python, java bool
func main() {
fmt.Println(x, y, z, c, python, java)
}
</div>
</div>
<div class="slide">
<h2>Variables</h2>
<p>
A var declaration can include initializers, one per variable.
<p>
If an initializer is present, the type can be omitted;
the variable will take the type of the initializer.
<div>
package main
import "fmt"
var x, y, z int = 1, 2, 3
var c, python, java = true, false, "no!"
func main() {
fmt.Println(x, y, z, c, python, java)
}
</div>
</div>
<div class="slide">
<h2>Variables</h2>
<p>
Inside a function, the <code>:=</code> short assignment statement
can be used in place of the short <code>var</code> declaration.
<p>
(Outside a function, every construct begins with a keyword and the
<code>:=</code> construct is not available.)
<div>
package main
import "fmt"
func main() {
var x, y, z int = 1, 2, 3
c, python, java := true, false, "no!"
fmt.Println(x, y, z, c, python, java)
}
</div>
</div>
<div class="slide">
<h2>Constants</h2>
<p>
Constants are declared like variables, but with the <code>const</code>
keyword.
<p>
Constants can be string, boolean, or numeric values.
<div>
package main
import "fmt"
const Pi = 3.14
func main() {
const World = "世界"
fmt.Println("Hello", World)
fmt.Println("Happy", Pi, "Day")
const Truth = true
fmt.Println("Go rules?", Truth)
}
</div>
</div>
<div class="slide">
<h2>Numeric Constants</h2>
<p>
Numeric constants are high-precision <i>values</i>.
<p>
An untyped constant takes the type needed by its context.
<p>
Try printing <code>needInt(Big)</code> too.
<div>
package main
import "fmt"
const (
Big = 1<<100
Small = Big>>99
)
func needInt(x int) int { return x*10 + 1 }
func needFloat(x float64) float64 {
return x*0.1
}
func main() {
fmt.Println(needInt(Small))
fmt.Println(needFloat(Small))
fmt.Println(needFloat(Big))
}
</div>
</div>
<div class="slide">
<h2>For</h2>
<p>
Go has only one looping construct, the <code>for</code> loop.
<p>
The basic <code>for</code> loop looks as it does in C or Java,
except that the <code>( )</code> are gone (they are not even optional)
and the <code>{ }</code> are required.
<div>
package main
import "fmt"
func main() {
sum := 0
for i := 0; i < 10; i++ {
sum += i
}
fmt.Println(sum)
}
</div>
</div>
<div class="slide">
<h2>For</h2>
<p>
As in C or Java, you can leave the pre and post statements empty.
<div>
package main
import "fmt"
func main() {
sum := 1
for ; sum < 1000; {
sum += sum
}
fmt.Println(sum)
}
</div>
</div>
<div class="slide">
<h2>For</h2>
<p>
At that point you can drop the semicolons:
C's <code>while</code> is spelled <code>for</code> in Go.
<div>
package main
import "fmt"
func main() {
sum := 1
for sum < 1000 {
sum += sum
}
fmt.Println(sum)
}
</div>
</div>
<div class="slide">
<h2>For</h2>
<p>
If you omit the loop condition, it loops forever.
<div>
package main
func main() {
for ; ; {
}
}
</div>
</div>
<div class="slide">
<h2>For</h2>
<p>
And with no clauses at all, the semicolons can be omitted,
so an infinite loop is compactly expressed.
<div>
package main
func main() {
for {
}
}
</div>
</div>
<div class="slide">
<h2>If</h2>
<p>
The <code>if</code> statement looks as it does in C or Java,
except that the <code>( )</code> are gone (they are not even optional)
and the <code>{ }</code> are required.
<p>
(Sound familiar?)
<div>
package main
import (
"fmt"
"math"
)
func sqrt(x float64) string {
if x < 0 {
return sqrt(-x) + "i"
}
return fmt.Sprint(math.Sqrt(x))
}
func main() {
fmt.Println(sqrt(2), sqrt(-4))
}
</div>
</div>
<div class="slide">
<h2>If</h2>
<p>
Like <code>for</code>, the <code>if</code> statement can start with a
short statement to execute before the condition.
<p>
Variables declared by the statement are only in scope until the end of
the <code>if</code>.
<p>
(Try using <code>v</code> in the last <code>return</code> statement.)
<div>
package main
import (
"fmt"
"math"
)
func pow(x, n, lim float64) float64 {
if v := math.Pow(x, n); v < lim {
return v
}
return lim
}
func main() {
fmt.Println(
pow(3, 2, 10),
pow(3, 3, 20),
)
}
</div>
</div>
<div class="slide">
<h2>If</h2>
<p>
Variables declared inside an <code>if</code>'s short statement are also
available inside any of the <code>else</code> blocks.
<div>
package main
import (
"fmt"
"math"
)
func pow(x, n, lim float64) float64 {
if v := math.Pow(x, n); v < lim {
return v
} else {
fmt.Printf("%g >= %g\n", v, lim)
}
// can't use v here, though
return lim
}
func main() {
fmt.Println(
pow(3, 2, 10),
pow(3, 3, 20),
)
}
</div>
</div>
<div class="slide">
<h2>Basic types</h2>
<p>
Go's basic types are
<pre>
bool
string
int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr
float32 float64
complex64 complex128
</pre>
<div>
package main
import (
"cmath"
"fmt"
)
var (
ToBe bool = false
MaxInt uint64 = 1<<64 - 1
z complex128 = cmath.Sqrt(-5+12i)
)
func main() {
const f = "%T(%v)\n"
fmt.Printf(f, ToBe, ToBe)
fmt.Printf(f, MaxInt, MaxInt)
fmt.Printf(f, z, z)
}
</div>
</div>
<div class="slide">
<h2>Structs</h2>
<p>
A <code>struct</code> is a collection of fields.
<p>
(And a <code>type</code> declaration does what you'd expect.)
<div>
package main
import "fmt"
type Vertex struct {
X int
Y int
}
func main() {
fmt.Println(Vertex{1, 2})
}
</div>
</div>
<div class="slide">
<h2>Struct Fields</h2>
<p>
Struct fields are accessed using a dot.
<div>
package main
import "fmt"
type Vertex struct {
X int
Y int
}
func main() {
v := Vertex{1, 2}
v.X = 4
fmt.Println(v.X)
}
</div>
</div>
<div class="slide">
<h2>Pointers</h2>
<p>
Go has pointers, but no pointer arithmetic.
<p>
Struct fields can be accessed through a struct pointer.
The indirection through the pointer is transparent.
<div>
package main
import "fmt"
type Vertex struct {
X int
Y int
}
func main() {
p := Vertex{1, 2}
q := &p
q.X = 1e9
fmt.Println(p)
}
</div>
</div>
<div class="slide">
<h2>Struct Literals</h2>
<p>
A struct literal denotes a newly allocated struct value by listing the
values of its fields.
<p>
You can list just a subset of fields by using the <code>Name:</code>
syntax. (And the order of named fields is irrelevant.)
<p>
The special prefix <code>&</code> constructs a pointer to a struct
literal.
<div>
package main
import "fmt"
type Vertex struct {
X, Y int
}
var (
p = Vertex{1, 2} // has type Vertex
q = &Vertex{1, 2} // has type *Vertex
r = Vertex{X: 1} // Y:0 is implicit
s = Vertex{} // X:0 and Y:0
)
func main() {
fmt.Println(p, q, r, s)
}
</div>
</div>
<div class="slide">
<h2>The <code>new</code> function</h2>
<p>
The expression <code>new(T)</code> allocates a zeroed <code>T</code>
value and returns a pointer to it.
<pre>var t *T = new(T)</pre>
<p>
or
<pre>t := new(T)</pre>
<div>
package main
import "fmt"
type Vertex struct {
X, Y int
}
func main() {
v := new(Vertex)
fmt.Println(v)
v.X, v.Y = 11, 9
fmt.Println(v)
}
</div>
</div>
<div class="slide">
<h2>Maps</h2>
<p>
A map maps keys to values.
<p>
<!-- TODO: empty part not true in compilers yet -->
Maps must be created with <code>make</code> (not <code>new</code>)
before use; the <code>nil</code> map is empty and cannot be assigned
to.
<div>
package main
import "fmt"
type Vertex struct {
Lat, Long float64
}
var m map[string]Vertex
func main() {
m = make(map[string]Vertex)
m["Bell Labs"] = Vertex{
40.68433, 74.39967,
}
fmt.Println(m["Bell Labs"])
}
</div>
</div>
<div class="slide">
<h2>Maps</h2>
<p>
Map literals are like struct literals, but the keys are required.
<div>
package main
import "fmt"
type Vertex struct {
Lat, Long float64
}
var m = map[string]Vertex{
"Bell Labs": Vertex{
40.68433, -74.39967,
},
"Google": Vertex{
37.42202, -122.08408,
},
}
func main() {
fmt.Println(m)
}
</div>
</div>
<div class="slide">
<h2>Maps</h2>
<p>
If the top-level type is just a type name, you can omit it from the
elements of the literal.
<div>
package main
import "fmt"
type Vertex struct {
Lat, Long float64
}
var m = map[string]Vertex{
"Bell Labs": {40.68433, -74.39967},
"Google": {37.42202, -122.08408},
}
func main() {
fmt.Println(m)
}
</div>
</div>
<div class="slide">
<h2>Slices</h2>
<p>
A slice points to an array of values and also includes a length.
<p>
<code>[]T</code> is a slice with elements of type <code>T</code>.
<div>
package main
import "fmt"
func main() {
p := []int{2, 3, 5, 7, 11, 13}
fmt.Println("p ==", p)
for i := 0; i < len(p); i++ {
fmt.Printf("p[%d] == %d\n",
i, p[i])
}
}
</div>
</div>
<div class="slide">
<h2>Slices</h2>
<p>
Slices can be re-sliced, creating a new slice value that points to the
same array.
<p>
The expression
<pre>s[lo:hi]</pre>
<p>
evaluates to a slice of the elements from <code>lo</code> through
<code>hi-1</code>, inclusive. Thus
<pre>s[lo:lo]</pre>
<p>
is empty and
<pre>s[lo:lo+1]</pre>
<p>
has one element.
<div>
package main
import "fmt"
func main() {
p := []int{2, 3, 5, 7, 11, 13}
fmt.Println("p ==", p)
fmt.Println("p[1:4] ==", p[1:4])
// missing low index implies 0
fmt.Println("p[:3] ==", p[:3])
// missing high index implies len(s)
fmt.Println("p[4:] ==", p[4:])
}
</div>
</div>
<div class="slide">
<h2>Slices</h2>
<p>
Slices are created with the <code>make</code> function. It works by
allocating a zeroed array and returning a slice that refers to that
array:
<pre>
a := make([]int, 5) // len(a)=5
</pre>
Slices have length and capacity. A slice's capacity is the maximum
length the slice can grow within the underlying array.
<p>
To specify a capacity, pass a third argument to <code>make</code>:
<p>
<pre>
b := make([]int, 0, 5)
// len(b)=0, cap(b)=5
</pre>
Slices can be grown by "re-slicing" (up to their capacity):
<p>
<pre>
b = b[:cap(b)] // len(b)=5, cap(b)=5
b = b[1:] // len(b)=4, cap(b)=4
</pre>
<div>
package main
import "fmt"
func main() {
a := make([]int, 5)
printSlice("a", a)
b := make([]int, 0, 5)
printSlice("b", b)
c := b[:2]
printSlice("c", c)
d := c[2:5]
printSlice("d", d)
}
func printSlice(s string, x []int) {
fmt.Printf("%s len=%d cap=%d %v\n",
s, len(x), cap(x), x)
}
</div>
</div>
<div class="slide">
<h2>Slices</h2>
<p>
The zero value of a slice is <code>nil</code>.
<p>
A nil slice has a length and capacity of 0.
<p>
<i>For more detail see the
"<a target="_blank" href="http://blog.golang.org/2011/01/go-slices-usage-and-internals.html">Go Slices: usage and internals</a>"
article.</i>
<div>
package main
import "fmt"
func main() {
var z []int
fmt.Println(z, len(z), cap(z))
if z == nil {
fmt.Println("nil!")
}
}
</div>
</div>
<div class="slide">
<h2>Functions</h2>
<p>
Functions are values too.
<div>
package main
import (
"fmt"
"math"
)
func main() {
hypot := func(x, y float64) float64 {
return math.Sqrt(x*x + y*y)
}
fmt.Println(hypot(3, 4))
}
</div>
</div>
<div class="slide">
<h2>Functions</h2>
<p>
And functions are full closures.
<p>
The <code>adder</code> function returns a closure.
Each closure is bound to its own <code>sum</code> variable.
<div>
package main
import "fmt"
func adder() func(int) int {
sum := 0
return func(x int) int {
sum += x
return sum
}
}
func main() {
pos, neg := adder(), adder()
for i := 0; i < 10; i++ {
fmt.Println(
pos(i),
neg(-2*i),
)
}
}
</div>
</div>
<div class="slide">
<h2>Range</h2>
<p>
The <code>range</code> form of the <code>for</code>
loop iterates over a slice or map.
<div>
package main
import "fmt"
var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}
func main() {
for i, v := range pow {
fmt.Printf("2**%d = %d\n", i, v)
}
}
</div>
</div>
<div class="slide">
<h2>Range</h2>
<p>
You can skip the key or value by assigning to <code>_</code>.
<p>
If you only want the index, drop the
&ldquo;<code>, value</code>&rdquo; entirely.
<div>
package main
import "fmt"
func main() {
pow := make([]int, 10)
for i := range pow {
pow[i] = 1&lt;&lt;uint(i)
}
for _, value := range pow {
fmt.Printf("%d\n", value)
}
}
</div>
</div>
<div class="slide">
<h2>Switch</h2>
<p>
You probably knew what <code>switch</code> was going to look like.
<p>
A case body breaks automatically, unless it ends with a <code>fallthrough</code> statement.
<div>
package main
import (
"fmt"
"runtime"
)
func main() {
fmt.Print("Go runs on ")
switch os := runtime.GOOS; os {
case "darwin":
fmt.Println("OS X.")
case "linux":
fmt.Println("Linux.")
default:
// freebsd, openbsd,
// plan9, windows...
fmt.Printf("%s.", os)
}
}
</div>
</div>
<div class="slide">
<h2>Switch</h2>
<p>
Switch cases evaluate cases from top to bottom, stopping when a
case succeeds.
<p>
(For example,
<pre>
switch i {
case 0:
case f():
}</pre>
<p>
does not call <code>f</code> if <code>i==0</code>.)
<div>
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println("When's Saturday?")
today := time.LocalTime().Weekday
switch time.Saturday {
case today+0:
fmt.Println("Today.")
case today+1:
fmt.Println("Tomorrow.")
case today+2:
fmt.Println("In two days.")
default:
fmt.Println("Too far away.")
}
}
</div>
</div>
<div class="slide">
<h2>Switch</h2>
<p>
Switch without a condition is the same as <code>switch true</code>.
<div>
package main
import (
"fmt"
"time"
)
func main() {
t := time.LocalTime()
switch {
case t.Hour < 12:
fmt.Println("Good morning!")
case t.Hour < 17:
fmt.Println("Good afternoon.")
default:
fmt.Println("Good evening.")
}
}
</div>
</div>
<div class="slide">
<h2>Exercise: Loops and Functions</h2>
<p>
As a simple way to play with functions and loops, implement
the square root function using Newton's method.
<p>
In this case, Newton's method is to approximate <code>Sqrt(x)</code>
by picking a starting point <i>z</i> and then repeating:
<center>
<img src="https://chart.googleapis.com/chart?cht=tx&chl=z=z-\frac{z^2-x}{2z}">
</center>
<p>
To begin with, just repeat that calculation 10 times and see how close you
get to the answer for various values (1, 2, 3, ...).
<p>
Next, change the loop condition to stop once the value has stopped
changing (or only changes by a very small delta).
See if that's more or fewer iterations.
How close are you to the <a target="_blank" href="http://golang.org/pkg/math/#Sqrt">math.Sqrt</a>?
<p>
Hint: to declare and initialize a floating point value, give it
floating point syntax or use a conversion:
<pre>
z := float64(1)
z := 1.0
</pre>
<div>
package main
import (
"fmt"
)
func Sqrt(x float64) float64 {
}
func main() {
fmt.Println(Sqrt(2))
}
</div>
</div>
<div class="slide">
<h2>Exercise: Maps</h2>
<p>
Implement <code>WordCount</code>. It should return a map of the
counts of each &ldquo;word&rdquo; in the string <code>s</code>.
The <code>wc.Test</code> function runs a test suite against the
provided function and prints success or failure.
<p>
You might find <a target="_blank" href="http://golang.org/pkg/strings/#Fields">strings.Fields</a> helpful.
<div>
package main
import (
"<span class="appengineMode">tour</span><span class="localMode">go-tour.googlecode.com/hg</span>/wc"
)
func WordCount(s string) map[string]int {
return map[string]int{"x": 1}
}
func main() {
wc.Test(WordCount)
}
</div>
</div>
<div class="slide">
<h2>Exercise: Slices</h2>
<p>
Implement <code>Pic</code>. It should return a slice of length
<code>dy</code>, each element of which is a slice of <code>dx</code>
8-bit unsigned integers. When you run the program, it will display
your picture, interpreting the integers as grayscale (well, bluescale)
values.
<p>
The choice of image is up to you.
Interesting functions include <code>x^y</code>, <code>(x+y)/2</code>, and <code>x*y</code>.
<p>
(You need to use a loop to allocate each <code>[]uint8</code> inside
the <code>[][]uint8</code>.)
<div>
package main
import "<span class="appengineMode">tour</span><span class="localMode">go-tour.googlecode.com/hg</span>/pic"
func Pic(dx, dy int) [][]uint8 {
}
func main() {
pic.Show(Pic)
}
</div>
</div>
<div class="slide">
<h2>Exercise: Fibonacci closure</h2>
<p>
Let's have some fun with functions.
<p>
Implement a <code>fibonacci</code> function that returns a function
(a closure) that returns successive fibonacci numbers.
<div>
package main
import "fmt"
// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
}
func main() {
f := fibonacci()
for i := 0; i < 10; i++ {
fmt.Println(f())
}
}
</div>
</div>
<div class="slide">
<h2>Advanced Exercise: Complex cube roots</h2>
<p>
Let's explore Go's built-in support for complex numbers via the
<code>complex64</code> and <code>complex128</code> types.
For cube roots, Newton's method amounts to repeating:
<center>
<img src="https://chart.googleapis.com/chart?cht=tx&chl=z=z-\frac{z^3-x}{3z^2}">
</center>
<p>
Find the cube root of 2, just to make sure the algorithm works.
There is a <a target="_blank" href="http://golang.org/pkg/cmath/#Pow">cmath.Pow</a> function.
<div>
package main
import "fmt"
func Cbrt(x complex128) complex128 {
}
func main() {
fmt.Println(Cbrt(2))
}
</div>
</div>
<div class="toc">Methods and Interfaces</div>
<div class="slide nocode">
<h2>Methods and Interfaces</h2>
</div>
<div class="slide">
<h2>Methods</h2>
<p>
Go does not have classes. However, you can define methods on struct
types.
<p>
The <i>method receiver</i> appears in its own argument list
between the <code>func</code> keyword and the method name.
<div>
package main
import (
"fmt"
"math"
)
type Vertex struct {
X, Y float64
}
func (v *Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
func main() {
v := &Vertex{3, 4}
fmt.Println(v.Abs())
}
</div>
</div>
<div class="slide">
<h2>Methods</h2>
<p>
In fact, you can define a method on <i>any</i> type you define in your
package, not just structs.
<p>
You cannot define a method on a type from another package, or on a
basic type.
<div>
package main
import (
"fmt"
"math"
)
type MyFloat float64
func (f MyFloat) Abs() float64 {
if f < 0 {
return float64(-f)
}
return float64(f)
}
func main() {
f := MyFloat(-math.Sqrt2)
fmt.Println(f.Abs())
}
</div>
</div>
<div class="slide">
<h2>Methods with pointer receivers</h2>
<p>
Methods can be associated with a named type or a pointer
to a named type.
<p>
We just saw two <code>Abs</code> methods. One on the
<code>*Vertex</code> pointer type and the other on the
<code>MyFloat</code> value type.
<p>
There are two reasons to use a pointer receiver.
First, to avoid copying the value on each method call (more efficient
if the value type is a large struct). Second, so that the method can
modify the value that its receiver points to.
</ol>
<p>
Try changing the declarations of the <code>Abs</code> and
<code>Scale</code> methods to use <code>Vertex</code> as the
receiver, instead of <code>*Vertex</code>.
<p>
The <code>Scale</code> method has no effect when <code>v</code> is a
<code>Vertex</code>. <code>Scale</code> mutates <code>v</code>. When
<code>v</code> is a value (non-pointer) type, the method sees a copy of
the <code>Vertex</code> and cannot mutate the original value.
<p>
<code>Abs</code> works either way. It only reads <code>v</code>.
It doesn't matter whether it is reading the original value (through a
pointer) or a copy of that value.
<div>
package main
import (
"fmt"
"math"
)
type Vertex struct {
X, Y float64
}
func (v *Vertex) Scale(f float64) {
v.X = v.X * f
v.Y = v.Y * f
}
func (v *Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
func main() {
v := &Vertex{3, 4}
v.Scale(5)
fmt.Println(v, v.Abs())
}
</div>
</div>
<div class="slide">
<h2>Interfaces</h2>
<p>
An interface type is defined by a set of methods.
<p>
A value of interface type can hold any value that
implements those methods.
<div>
package main
import (
"fmt"
"math"
)
type Abser interface {
Abs() float64
}
func main() {
var a Abser
f := MyFloat(-math.Sqrt2)
v := Vertex{3, 4}
a = f // a MyFloat implements Abser
a = &v // a *Vertex implements Abser
a = v // a Vertex, does NOT
// implement Abser
fmt.Println(a.Abs())
}
type MyFloat float64
func (f MyFloat) Abs() float64 {
if f < 0 {
return float64(-f)
}
return float64(f)
}
type Vertex struct {
X, Y float64
}
func (v *Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
</div>
</div>
<div class="slide">
<h2>Interfaces</h2>
<p>
A type implements an interface by implementing the methods.
<p>
<i>There is no explicit declaration of intent.</i>
<p>
Implicit interfaces decouple implementation packages from the packages
that define the interfaces: neither depends on the other.
<p>
It also encourages the definition of precise interfaces, because you
don't have to find every implementation and tag it with the new
interface name.
<p>
<a target="_blank" href="http://golang.org/pkg/io/">Package io</a> defines <code>Reader</code> and <code>Writer</code>; you don't have to.
<div>
package main
import (
"fmt"
"os"
)
type Reader interface {
Read(b []byte) (n int, err os.Error)
}
type Writer interface {
Write(b []byte) (n int, err os.Error)
}
type ReadWriter interface {
Reader
Writer
}
func main() {
var w Writer
// os.Stdout implements Writer
w = os.Stdout
fmt.Fprintf(w, "hello, writer\n")
}
</div>
</div>
<div class="slide">
<h2>Errors</h2>
<p>
An error is anything that can describe itself:
<pre>
package os
type Error interface {
String() string
}
</pre>
<div>
package main
import (
"fmt"
"os"
"time"
)
type MyError struct {
When *time.Time
What string
}
func (e *MyError) String() string {
return fmt.Sprintf("at %v, %s",
e.When, e.What)
}
func run() os.Error {
return &MyError{
time.LocalTime(),
"it didn't work",
}
}
func main() {
if err := run(); err != nil {
fmt.Println(err)
}
}
</div>
</div>
<div class="slide">
<h2>Web servers</h2>
<p>
<a target="_blank" href="http://golang.org/pkg/http/">Package http</a> serves HTTP requests using any value
that implements <code>http.Handler</code>:
<pre>
package http
type Handler interface {
ServeHTTP(w ResponseWriter,
r *Request)
}
</pre>
<p>
In this example, the type <code>MyHandler</code> implements <code>http.Handler</code>.
<p>
<span class="localMode">
Visit <a href="http://localhost:4000/" target="_blank">http://localhost:4000/</a> to see the greeting.
</span>
<span class="appengineMode">
<b>Note:</b> This example won't run through the web-based tour user
interface. To try writing web servers you may want to
<a target="_blank" href="http://golang.org/doc/install.html">Install
Go</a>.
</span>
<div>
package main
import (
"fmt"
"http"
)
type Hello struct{}
func (h Hello) ServeHTTP(
w http.ResponseWriter,
r *http.Request) {
fmt.Fprint(w, "Hello!")
}
func main() {
var h Hello
http.ListenAndServe("localhost:4000",h)
}
</div>
</div>
<div class="slide">
<h2>Images</h2>
<p>
<a target="_blank" href="http://golang.org/pkg/image/#Image">Package image</a> defines the <code>Image</code>
interface:
<pre>
package image
type Image interface {
ColorModel() ColorModel
Bounds() Rectangle
At(x, y int) Color
}</pre>
<p>
(See <a target="_blank" href="http://golang.org/pkg/image/#Image">the
documentation</a> for all the details.)
<p>
<code>Color</code> and <code>ColorModel</code> are interfaces too,
but we'll ignore that by using the predefined implementations
<code>image.RGBAColor</code> and <code>image.RGBAColorModel</code>.
<div>
package main
import (
"fmt"
"image"
)
func main() {
m := image.NewRGBA(100, 100)
fmt.Println(m.Bounds())
fmt.Println(m.At(0, 0).RGBA())
}
</div>
</div>
<div class="slide">
<h2>Exercise: Errors</h2>
<p>
Copy your <code>Sqrt</code> function from the earlier exercises and
modify it to return an <code>os.Error</code> value.
<p>
<code>Sqrt</code> should return a non-nil error value when given a
negative number, as it doesn't support complex numbers.
<p>
Create a new type
<pre>
type ErrNegativeSqrt float64</pre>
<p>
and make it an <code>os.Error</code> by giving it a
<pre>
func (e ErrNegativeSqrt) String() string</pre>
<p>
method such that <code>ErrNegativeSqrt(-2).String()</code> returns
<code>"cannot Sqrt negative number: -2"</code>.
<p>
<b>Note:</b> a call to <code>fmt.Print(e)</code> inside the
<code>String</code> method will send the program into an infinite loop.
You can avoid this by converting <code>e</code> first:
<code>fmt.Print(float64(e))</code>. Why?
<p>
Change your <code>Sqrt</code> function to return an
<code>ErrNegativeSqrt</code> value when given a negative number.
<div>
package main
import (
"fmt"
"os"
)
func Sqrt(f float64) (float64, os.Error) {
return 0, nil
}
func main() {
fmt.Println(Sqrt(2))
fmt.Println(Sqrt(-2))
}
</div>
</div>
<div class="slide localMode">
<h2>Exercise: HTTP Handlers</h2>
<p>
Implement the following types and define ServeHTTP methods on them.
Register them to handle specific paths in your web server.
<pre>type String string
type Struct struct {
Greeting string
Punct string
Who string
}</pre>
<p>
For example, you should be able to register handlers using:
<pre>http.Handle("/string", String("I'm a frayed knot."))
http.Handle("/struct", &Struct{"Hello", ":", "Gophers!"})</pre>
<div>
package main
import (
"http"
)
func main() {
// your http.Handle calls here
http.ListenAndServe("localhost:4000", nil)
}
</div>
</div>
<div class="slide">
<h2>Exercise: Images</h2>
<p>
Remember the picture generator you wrote earlier?
Let's write another one, but this time it will return
an implementation of <code>image.Image</code> instead of a slice of data.
<p>
Define your own <code>Image</code> type, implement
<a target="_blank" href="http://golang.org/pkg/image/#Image" target="_blank">the necessary methods</a>,
and call <code>pic.ShowImage</code>.
<p>
<code>Bounds</code> should return a <code>image.Rectangle</code>, like
<code>image.Rect(0, 0, w, h)</code>.
<p>
<code>ColorModel</code> should return <code>image.RGBAColorModel</code>.
<p>
<code>At</code> should return a color;
the value <code>v</code> in the last picture generator corresponds to
<code>image.RGBAColor{v, v, 255, 255}</code> in this one.
<div>
package main
import (
"image"
"<span class="appengineMode">tour</span><span class="localMode">go-tour.googlecode.com/hg</span>/pic"
)
type Image struct{}
func main() {
m := Image{}
pic.ShowImage(m)
}
</div>
</div>
<div class="slide">
<h2>Exercise: Rot13 Reader</h2>
<p>
A common pattern is an
<a target="_blank" href="http://golang.org/pkg/io/#Reader">io.Reader</a> that wraps
another <code>io.Reader</code>, modifying the stream in some way.
<p>
For example, the
<a target="_blank" href="http://golang.org/pkg/compress/gzip/#Decompressor.NewReader">gzip.NewReader</a>
function takes an <code>io.Reader</code> (a stream of gzipped data)
and returns a <code>*gzip.Decompressor</code> that also implements
<code>io.Reader</code> (a stream of the decompressed data).
<p>
Implement a <code>rot13Reader</code> that implements
<code>io.Reader</code> and reads from an <code>io.Reader</code>,
modifying the stream by applying the
<a target="_blank" href="http://en.wikipedia.org/wiki/ROT13">ROT13</a>
substitution cipher to all alphabetical characters.
<p>
The <code>rot13Reader</code> type is provided for you. Make it an
<code>io.Reader</code> by implementing its <code>Read</code> method.
<div>
package main
import (
"io"
"os"
"strings"
)
type rot13Reader struct {
r io.Reader
}
func main() {
s := strings.NewReader(
"Lbh penpxrq gur pbqr!")
r := rot13Reader{s}
io.Copy(os.Stdout, &r)
}
</div>
</div>
<div class="toc">Concurrency</div>
<div class="slide nocode">
<h2>Concurrency</h2>
</div>
<div class="slide">
<h2>Goroutines</h2>
<p>
A <i>goroutine</i> is a lightweight thread managed by the Go runtime.
<pre>go f(x, y, z)</pre>
<p>
starts a new goroutine running
<pre>f(x, y, z)</pre>
<p>
The evaluation
of <code>f</code>, <code>x</code>, <code>y</code>, and <code>z</code>
happens in the current goroutine and the execution of <code>f</code>
happens in the new goroutine.
<p>
Goroutines run in the same address space, so access to shared memory
must be synchronized. The <code><a href="http://golang.org/pkg/sync/"
target="_blank">sync</a></code> package provides useful primitives,
although you won't need them much in Go as there are other primitives.
(See the next slide.)
<div>
package main
import (
"fmt"
"<span class="appengineMode">runtime</span><span class="localMode">time</span>"
)
func say(s string) {
for i := 0; i < 5; i++ {
<span class="appengineMode">runtime.Gosched()</span><span class="localMode">time.Sleep(100e6)</span>
fmt.Println(s)
}
}
func main() {
go say("world")
say("hello")
}
</div>
</div>
<div class="slide">
<h2>Channels</h2>
<p>
Channels are a typed conduit through which you can send and receive values with the channel operator, <code>&lt;-</code>.
<pre>
ch <- v // Send v to channel ch.
v := <-ch // Receive from ch, and
// assign value to v.
</pre>
<p>
(The data flows in the direction of the "arrow".)
<p>
Like maps and slices, channels must be created before use:
<pre>
ch := make(chan int)
</pre>
<p>
By default, sends and receives block until the other side is ready.
This allows goroutines to synchronize without explicit locks or
condition variables.
<div>
package main
import "fmt"
func sum(a []int, c chan int) {
sum := 0
for _, v := range a {
sum += v
}
c <- sum // send sum to c
}
func main() {
a := []int{7, 2, 8, -9, 4, 0}
c := make(chan int)
go sum(a[:len(a)/2], c)
go sum(a[len(a)/2:], c)
x, y := <-c, <-c // receive from c
fmt.Println(x, y, x + y)
}
</div>
</div>
<div class="slide">
<h2>Buffered Channels</h2>
<p>
Channels can be <i>buffered</i>. Provide the buffer length as the
second argument to <code>make</code> to initialize a buffered channel:
<pre>
ch := make(chan int, 100)
</pre>
<p>
Sends to a buffered channel block only when the buffer is full.
Receives block when the buffer is empty.
<p>
Modify the example to overfill the buffer and see what happens.
<div>
package main
import "fmt"
func main() {
c := make(chan int, 2)
c <- 1
c <- 2
fmt.Println(<-c)
fmt.Println(<-c)
}
</div>
</div>
<div class="slide">
<h2>Range and Close</h2>
<p>
A sender can <code>close</code> a channel to indicate that no more
values will be sent. Receivers can test whether a channel has been
closed by assigning a second parameter to the receive expression: after
<pre>
v, ok := &lt;-ch</pre>
<p>
<code>ok</code> is <code>false</code> if there are no more values to
receive and the channel is closed.
<p>
The loop <code>for i := range c</code> receives values from the
channel repeatedly until it is closed.
<p>
<b>Note:</b> Only the sender should close a channel, never the
receiver. Sending on a closed channel will cause a panic.
<p>
<b>Another note</b>: Channels aren't like files; you don't usually
need to close them. Closing is only necessary when the receiver must be
told there are no more values coming.
<div>
package main
import (
"fmt"
)
func fibonacci(n int, c chan int) {
x, y := 1, 1
for i := 0; i < n; i++ {
c <- x
x, y = y, x + y
}
close(c)
}
func main() {
c := make(chan int, 10)
go fibonacci(cap(c), c)
for i := range c {
fmt.Println(i)
}
}
</div>
</div>
<div class="slide">
<h2>Select</h2>
<p>
The <code>select</code> statement lets a goroutine wait on multiple
communication operations.
<p>
A <code>select</code> blocks until one of its cases can run, then it
executes that case. It chooses one at random if multiple are ready.
<div>
package main
import "fmt"
func fibonacci(c, quit chan int) {
x, y := 1, 1
for {
select {
case c <- x:
x, y = y, x + y
case <-quit:
fmt.Println("quit")
return
}
}
}
func main() {
c := make(chan int)
quit := make(chan int)
go func() {
for i := 0; i < 10; i++ {
fmt.Println(<-c)
}
quit <- 0
}()
fibonacci(c, quit)
}
</div>
</div>
<div class="slide">
<h2>Default Selection</h2>
<p>
The <code>default</code> case in a <code>select</code> is run if no
other case is ready.
<p>
Use a <code>default</code> case to try a send or receive without
blocking:
<pre>
select {
case i := <-c:
// use i
default:
// receiving from c would block
}</pre>
<p>
<span class="appengineMode">
<b>Note:</b> This example won't run through the web-based tour user
interface because the
<a target="_blank" href="http://golang.org/doc/play/">sandbox
environment</a> has no concept of time. You may want to
<a target="_blank" href="http://golang.org/doc/install.html">install
Go</a> to see this example in action.
</span>
<div>
package main
import (
"fmt"
"time"
)
func main() {
tick := time.Tick(1e8)
boom := time.After(5e8)
for {
select {
case <-tick:
fmt.Println("tick.")
case <-boom:
fmt.Println("BOOM!")
return
default:
fmt.Println(" .")
time.Sleep(5e7)
}
}
}
</div>
</div>
<div class="slide nocode">
<h2>Exercise: Equivalent Binary Trees</h2>
<p>
There can be many different binary trees with the same sequence of
values stored at the leaves.
For example, here are two binary trees storing the sequence
1, 1, 2, 3, 5, 8, 13.
<img src="static/fig4.png">
<p>
A function to check whether two binary trees store the same sequence is
quite complex in most languages. We'll use Go's concurrency and
channels to write a simple solution.
<p>
This example uses the <code>tree</code> package, which defines the type:
<pre>
type Tree struct {
Left *Tree
Value int
Right *Tree
}
</pre>
</div>
<div class="slide">
<h2>Exercise: Equivalent Binary Trees</h2>
<p>
<b>1.</b> Implement the <code>Walk</code> function.
<p>
<b>2.</b> Test the <code>Walk</code> function.
<p>
The function <code>tree.New(k)</code> constructs a randomly-structured
binary tree holding the values <code>k</code>, <code>2k</code>, <code>3k</code>, ...,
<code>10k</code>.
<p>
Create a new channel <code>ch</code> and kick off the walker:
<pre>
go Walk(tree.New(1), ch)
</pre>
<p>
Then read and print 10 values from the channel.
It should be the numbers 1, 2, 3, ..., 10.
<p>
<b>3.</b> Implement the <code>Same</code> function using <code>Walk</code>
to determine whether <code>t1</code> and <code>t2</code> store the same values.
<p>
<b>4.</b> Test the <code>Same</code> function.
<p>
<code>Same(tree.New(1), tree.New(1))</code> should return true, and
<code>Same(tree.New(1), tree.New(2))</code> should return false.
<div>
package main
import "<span class="appengineMode">tour</span><span class="localMode">go-tour.googlecode.com/hg</span>/tree"
// Walk walks the tree t sending all values
// from the tree to the channel ch.
func Walk(t *tree.Tree, ch chan int)
// Same determines whether the trees
// t1 and t2 contain the same values.
func Same(t1, t2 *tree.Tree) bool
func main() {
}
</div>
</div>
<div class="slide">
<h2>Exercise: Web Crawler</h2>
<p>
In this exercise you'll use Go's concurrency features to
parallelize a web crawler.
<p>
Modify the <code>Crawl</code> function to fetch URLs in parallel
without fetching the same URL twice.
<div>
package main
import (
"os"
"fmt"
)
type Fetcher interface {
// Fetch returns the body of URL and
// a slice of URLs found on that page.
Fetch(url string) (body string, urls []string, err os.Error)
}
// Crawl uses fetcher to recursively crawl
// pages starting with url, to a maximum of depth.
func Crawl(url string, depth int, fetcher Fetcher) {
// TODO: Fetch URLs in parallel.
// TODO: Don't fetch the same URL twice.
// This implementation doesn't do either:
if depth <= 0 {
return
}
body, urls, err := fetcher.Fetch(url)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("found: %s %q\n", url, body)
for _, u := range urls {
Crawl(u, depth-1, fetcher)
}
return
}
func main() {
Crawl("http://golang.org/", 4, fetcher)
}
// fakeFetcher is Fetcher that returns canned results.
type fakeFetcher map[string]*fakeResult
type fakeResult struct {
body string
urls []string
}
func (f *fakeFetcher) Fetch(url string) (string, []string, os.Error) {
if res, ok := (*f)[url]; ok {
return res.body, res.urls, nil
}
return "", nil, fmt.Errorf("not found: %s", url)
}
// fetcher is a populated fakeFetcher.
var fetcher = &fakeFetcher{
"http://golang.org/": &fakeResult{
"The Go Programming Language",
[]string{
"http://golang.org/pkg/",
"http://golang.org/cmd/",
},
},
"http://golang.org/pkg/": &fakeResult{
"Packages",
[]string{
"http://golang.org/",
"http://golang.org/cmd/",
"http://golang.org/pkg/fmt/",
"http://golang.org/pkg/os/",
},
},
"http://golang.org/pkg/fmt/": &fakeResult{
"Package fmt",
[]string{
"http://golang.org/",
"http://golang.org/pkg/",
},
},
"http://golang.org/pkg/os/": &fakeResult{
"Package os",
[]string{
"http://golang.org/",
"http://golang.org/pkg/",
},
},
}
</div>
</div>
<div class="slide nocode">
<h2>Where to Go from here...</h2>
<p class="appengineMode">
You can get started by
<a href="http://golang.org/doc/install.html">installing Go</a> or
downloading the
<a href="http://code.google.com/appengine/downloads.html#Google_App_Engine_SDK_for_Go">Go App Engine SDK</a>.
</p>
<p>
<span class="appengineMode">Once you have Go on your machine, the</span>
<span class="localMode">The</span>
<a target="_blank" href="http://golang.org/doc/docs.html">Go Documentation</a>
is a great place to
<span class="appengineMode">continue</span>
<span class="localMode">start</span>.
It contains references, tutorials, videos, and more.
<p>
If you need help with the standard library,
see the <a target="_blank" href="http://golang.org/pkg/">package
reference</a>. For help with the language itself, you might be
surprised to find the
<a target="_blank" href="http://golang.org/doc/go_spec.html">Language
Spec</a> is quite readable.
<p>
If you're interested in writing web applications,
see the
<a target="_blank" href="http://golang.org/doc/codelab/wiki/">Wiki
Codelab</a>.
<p>
If you want to further explore Go's concurrency model, see the
<a target="_blank" href="http://golang.org/doc/codewalk/sharemem/">Share Memory by Communicating</a>
codewalk.
<p>
The <a target="_blank" href="http://golang.org/doc/codewalk/functions/">First Class Functions in Go</a>
codewalk gives an interesting perspective on Go's function types.
<p>
The <a target="_blank" href="http://blog.golang.org/">Go Blog</a> has a
large archive of informative Go articles.
<p>
Visit <a target="_blank" href="http://golang.org">golang.org</a> for
more.
</div>
</div><!-- end slides -->
</body>
</html>