| <!-- |
| TODO |
| |
| Finish slides. |
| pgup/dn on nocode slides |
| <title> update for each page |
| discuss iota |
| detect #nn changes |
| gofmt button |
| highlight error line |
| --> |
| <html> |
| |
| <head> |
| <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'> |
| <link rel="stylesheet" href="tour.css" charset="utf-8"> |
| <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script> |
| <script src="tour.js"></script> |
| </head> |
| |
| <body> |
| |
| <h2 class="slidenum" id="num"></h2> |
| <div id="topnav" class="nav"> |
| <button id="tocbtn">INDEX</button> |
| </div> |
| <h1>A Tour of Go</h1> |
| |
| <ol id="toc"></ol> |
| |
| <div id="slides" class="slides codeleft"> |
| |
| <div class="toc">Introduction</div> |
| |
| <div class="slide"> |
| <h2>Hello, 世界</h2> |
| <p> |
| Welcome to a tour of the Go programming language. |
| <p> |
| To run this program, click the Compile button (or type Shift-Enter). |
| <p> |
| The programs in the tour are meant to be starting points for your own experimentation. |
| Edit the program and run it again. |
| <div> |
| package main |
| |
| import "fmt" |
| |
| func main() { |
| fmt.Println("Hello, 世界") |
| } |
| </div> |
| </div> |
| |
| <div class="slide"> |
| <h2>Hey</h2> |
| <p> |
| Now that the formalities are over, we can look at what's going on. |
| When you type Shift-Enter, your computer compiles and runs the |
| program and displays the result below. |
| <p> |
| Example programs demonstrate different aspects of Go. |
| Play with them to try new things and explore the language. |
| <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("Hey") |
| } |
| </div> |
| </div> |
| |
| <div class="slide"> |
| <h2>Imports</h2> |
| <p> |
| This program shows a 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>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>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>Pi</code> is an exported name; so is <code>PI</code>; not <code>pi</code>. |
| <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. |
| <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 function parameters share a type, |
| you can omit the type from all but the last. |
| <p> |
| In this example, we shortened <code>x int, y int</code> to <code>x, y int</code>. |
| <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 zero or more 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> |
| Function results can be named, in which case 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; |
| like in function argument lists, the type is last. |
| <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" |
| |
| 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 way!" |
| |
| 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. |
| <div> |
| package main |
| |
| import "fmt" |
| |
| func main() { |
| var x, y, z int = 1, 2, 3 |
| c, python, java := true, false, "certainly not" |
| |
| 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. |
| <div> |
| package main |
| |
| import "fmt" |
| |
| const Beta = 'β' |
| |
| const ( |
| Pi = 3.14 |
| World = "世界" |
| ) |
| |
| func main() { |
| fmt.Println("Hello", World) |
| fmt.Println("Happy", Pi, "Day") |
| } |
| </div> |
| </div> |
| |
| <div class="slide"> |
| <h2>Constants</h2> |
| <p> |
| Constants are high-precision <i>values</i>: numbers and strings. |
| <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), |
| needFloat(Small), needFloat(Big)) |
| } |
| </div> |
| </div> |
| |
| <div class="slide"> |
| <h2>For</h2> |
| <p> |
| Go has a single looping construct, the <code>for</code> loop. |
| <p> |
| The basic <code>for</code> loop looks like it does in C or Java, |
| except that the <code>( )</code> are gone 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> |
| Like 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> |
| Like before, you can drop the semicolons. |
| <div> |
| package main |
| |
| func main() { |
| for { |
| } |
| } |
| </div> |
| </div> |
| |
| <div class="slide"> |
| <h2>If</h2> |
| <p> |
| The <code>if</code> statement looks like it does in C or Java, |
| except that the <code>( )</code> are gone and the <code>{ }</code> are required. |
| (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>. |
| (Try adding <code>neg</code> to the <code>fmt.Sprint</code> call.) |
| <div> |
| package main |
| |
| import ( |
| "fmt" |
| "math" |
| ) |
| |
| func sqrt(x float64) string { |
| if neg := math.Signbit(x); neg { |
| return sqrt(-x) + "i" |
| } |
| return fmt.Sprint(math.Sqrt(x)) |
| } |
| |
| func main() { |
| fmt.Println(sqrt(2), sqrt(-4)) |
| } |
| </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 |
| 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() { |
| fmt.Printf("%T(%v) %T(%v) %T(%v)\n", |
| ToBe, ToBe, |
| MaxInt, MaxInt, |
| 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 Point struct { |
| X int |
| Y int |
| } |
| |
| func main() { |
| fmt.Println(Point{1, 2}) |
| } |
| </div> |
| </div> |
| |
| <div class="slide"> |
| <h2>Pointers</h2> |
| <p> |
| Go has pointers, but no pointer arithmetic. |
| <div> |
| package main |
| |
| import "fmt" |
| |
| type Point struct { |
| X int |
| Y int |
| } |
| |
| func main() { |
| p := Point{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 struct value by listing the values |
| of its fields. |
| <p> |
| You can list just a few fields by using the <code>Name:</code> syntax. |
| <p> |
| The special prefix <code>&</code> constructs a pointer to a struct literal. |
| <div> |
| package main |
| |
| import "fmt" |
| |
| type Point struct { |
| X, Y int |
| } |
| |
| var ( |
| p = Point{1, 2} // has type Point |
| q = &Point{1, 2} // has type *Point |
| r = Point{X: 1} // Y:0 is implicit |
| s = Point{} // X:0 and Y:0 are implicit |
| ) |
| |
| func main() { |
| fmt.Println(p, q, r, s) |
| } |
| </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> before use; the <code>nil</code> map is empty |
| and cannot be assigned to. |
| <div> |
| package main |
| |
| import "fmt" |
| |
| type Point struct { |
| Lat, Long float64 |
| } |
| |
| var m map[string]Point |
| |
| func main() { |
| m = make(map[string]Point) |
| m["Bell Labs"] = Point{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 Point struct { |
| Lat, Long float64 |
| } |
| |
| var m = map[string]Point{ |
| "Bell Labs": Point{40.68433, -74.39967}, |
| "Google": Point{37.42202, -122.08408}, |
| } |
| |
| func main() { |
| fmt.Println(m) |
| } |
| </div> |
| </div> |
| |
| <div class="slide"> |
| <h2>Slices</h2> |
| <p> |
| A slice points at an array of values and also includes a length. |
| <div> |
| package main |
| |
| import "fmt" |
| |
| type Point struct { |
| Lat, Long float64 |
| } |
| |
| var places = []Point{ |
| Point{40.68433, -74.39967}, |
| Point{37.42202, -122.08408}, |
| } |
| |
| var empty []Point |
| |
| var five = make([]Point, 5) |
| |
| func main() { |
| fmt.Println("Empty: ", len(empty), empty) |
| fmt.Println("Five: ", len(five), five) |
| fmt.Println("Places:", len(places), places) |
| |
| primes := []int{2, 3, 5, 7, 11, 13} |
| fmt.Println("Primes:", primes) |
| } |
| </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. |
| <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(i, 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 key, value := range pow { |
| fmt.Printf("2^%d = %d\n", key, value) |
| } |
| } |
| </div> |
| </div> |
| |
| <div class="slide"> |
| <h2>Range</h2> |
| <p> |
| You can skip the key or value by assigning to <code>_</code>. |
| <p> |
| You can also drop the “<code>, value</code>” entirely. |
| <div> |
| package main |
| |
| import "fmt" |
| |
| func main() { |
| pow := make([]int, 10) |
| for i := range pow { |
| pow[i] = 1<<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() { |
| switch os := runtime.GOOS; os { |
| case "darwin": |
| fmt.Printf("Go runs on OS X.\n") |
| case "freebsd": |
| fmt.Printf("Go runs on FreeBSD.\n") |
| case "linux": |
| fmt.Printf("Go runs on Linux.\n") |
| case "plan9": |
| fmt.Printf("Go runs on Plan 9.\n") |
| case "windows": |
| fmt.Printf("Go runs on Windows.\n") |
| default: |
| fmt.Printf("I forgot %s.\n", os) |
| } |
| } |
| </div> |
| </div> |
| |
| <div class="slide"> |
| <h2>Switch</h2> |
| <p> |
| Switch cases don't have to be constants; the first match wins. |
| |
| <div> |
| package main |
| |
| import ( |
| "fmt" |
| "time" |
| ) |
| |
| func main() { |
| today := time.LocalTime().Weekday |
| switch 6 { |
| case today+0: |
| fmt.Println("It's Saturday.") |
| case today+1: |
| fmt.Println("Tomorrow's Saturday.") |
| case today+2: |
| fmt.Println("Two days to Saturday.") |
| default: |
| fmt.Println("Saturday is 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}{2x}"> |
| </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. |
| 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(0) |
| z := 0.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 “word” in the string <code>s</code>. |
| With the binary running, visit <a target="_blank" href="http://localhost:4000/">this page</a> |
| to count words interactively. |
| <p> |
| You might find <a target="_blank" href="http://golang.org/pkg/strings/#Fields">strings.Fields</a> helpful. |
| |
| <div> |
| package main |
| |
| import ( |
| "go-tour.googlecode.com/hg/wc" |
| ) |
| |
| func WordCount(s string) map[string]int { |
| return map[string]int{"x": 1} |
| } |
| |
| func main() { |
| wc.Serve(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>. |
| |
| <div> |
| package main |
| |
| import "go-tour.googlecode.com/hg/pic" |
| |
| func Pic(dx, dy int) [][]uint8 { |
| } |
| |
| func main() { |
| pic.Show(Pic) |
| } |
| </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}{3x^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="slide"> |
| <h2>Advanced Exercise: High Precison</h2> |
| <p> |
| <a target="_blank" href="http://golang.org/pkg/big/">Package big</a> |
| implements arbitrary precision integer arithmetic. |
| Convert your square root program to work in fixed point arithmetic |
| for some number of decimal places <code>P</code> and then compute |
| 50 digits of the square of 2. Double check them against the |
| constant listed in the <a target="_blank" href="http://golang.org/pkg/math/">package math documentation</a>. |
| |
| <div> |
| package main |
| |
| func main() { |
| } |
| </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> |
| Methods can be associated with any named type, |
| but only the package that defines a type can |
| define methods on it. |
| |
| <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 Point struct { |
| X, Y float64 |
| } |
| |
| func (p *Point) Abs() float64 { |
| return math.Sqrt(p.X*p.X + p.Y*p.Y) |
| } |
| |
| func main() { |
| p := &Point{3, 4} |
| fmt.Println(p.Abs()) |
| } |
| </div> |
| </div> |
| |
| <div class="slide"> |
| <h2>Methods</h2> |
| <p> |
| Methods can be associated with <i>any</i> named 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>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) |
| p = Point{3, 4} |
| ) |
| |
| a = f // f, a MyFloat, implements Abser |
| a = &p // &p, a *Point, implements Abser |
| a = p // p, a Point, 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 Point struct { |
| X, Y float64 |
| } |
| |
| func (p *Point) Abs() float64 { |
| return math.Sqrt(p.X*p.X + p.Y*p.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> |
| This decouples 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 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 |
| w = os.Stdout // os.Stdout implements our interface |
| 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" |
| "time" |
| "os" |
| ) |
| |
| type MyError struct { |
| When *time.Time |
| What string |
| } |
| |
| func (e *MyError) String() string { |
| return "at " + e.When.String() + ", " + 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 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, req *Request) |
| } |
| </pre> |
| <p> |
| In this example, the type <code>MyHandler</code> implements <code>http.Handler</code>. |
| <p> |
| Visit <a href="http://localhost:4000/" target="_blank">http://localhost:4000/</a> to see the greeting. |
| <div> |
| package main |
| |
| import ( |
| "fmt" |
| "http" |
| "log" |
| ) |
| |
| type MyHandler struct{} |
| |
| func (h MyHandler) ServeHTTP(w http.ResponseWriter, |
| r *http.Request) { |
| fmt.Fprint(w, "Hello!") |
| } |
| |
| func main() { |
| var h MyHandler |
| err := http.ListenAndServe("localhost:4000", h) |
| if err != nil { |
| log.Fatal(err) |
| } |
| } |
| </div> |
| </div> |
| |
| <div class="slide"> |
| <h2>Images</h2> |
| <p> |
| <a href="http://golang.org/pkg/image/#Image">Package image</a> defines the <code>Image</code> |
| interface: |
| <pre> |
| package image |
| |
| type Image interface { |
| <span>// ColorModel returns the Image's ColorModel.</span> |
| ColorModel() ColorModel |
| |
| <span>// Bounds returns the domain for which At can return non-zero color.</span> |
| <span>// The bounds do not necessarily contain the point (0, 0).</span> |
| Bounds() Rectangle |
| |
| <span>// At returns the color of the pixel at (x, y).</span> |
| <span>// At(Bounds().Min.X, Bounds().Min.Y) returns the upper-left pixel of the grid.</span> |
| <span>// At(Bounds().Max.X-1, Bounds().Max.Y-1) returns the lower-right one.</span> |
| At(x, y int) Color |
| }</pre> |
| <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: Hello, world 2.0</h2> |
| <p> |
| Implement an <code>http.Handler</code> that responds to every request by saying |
| <pre> Hello, <i>name</i></pre> |
| <p> |
| where <i>name</i> is the value of the request parameter <code>name</code>. |
| <p> |
| For example, <a target="_blank" |
| href="http://localhost:4000/?name=Joe">http://localhost:4000/?name=Joe</a> |
| should display |
| <pre> Hello, Joe</pre> |
| <p> |
| Hint: use the <code><a href="http://golang.org/pkg/http/#Request.FormValue" |
| target="_blank">FormValue</a></code> method of |
| <code>*http.Request</code> to access the request parameters. |
| <div> |
| package main |
| |
| import ( |
| "http" |
| ) |
| |
| func main() { |
| var h http.Handler = // your value here |
| http.ListenAndServe("localhost:4000", h) |
| } |
| </div> |
| </div> |
| |
| <div class="slide"> |
| <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 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" |
| "go-tour.googlecode.com/hg/pic" |
| ) |
| |
| func main() { |
| m := ... my image |
| pic.ShowImage(m) |
| } |
| </div> |
| </div> |
| |
| <div class="toc">Concurrency</div> |
| |
| <div class="slide nocode"> |
| <h2>Concurrency</h2> |
| </div> |
| |
| <div class="slide"> |
| <h2>Goroutines</h2> |
| |
| <p> |
| <code>go f(x, y, z)</code> starts a new goroutine running <code>f(x, |
| y, z)</code>. |
| <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 share memory, 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. |
| <div> |
| package main |
| |
| import ( |
| "fmt" |
| "time" |
| ) |
| |
| func say(s string) { |
| for i := 0; i < 5; i++ { |
| time.Sleep(100e6) |
| 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><-</code>. |
| <pre> |
| ch <- v // send v to channel ch |
| v := <-ch // receive from ch, 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> |
| 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 only block 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: in <code>v, ok := |
| <-ch</code>, <code>ok</code> is <code>false</code> if <code>ch</code> is closed. |
| |
| <p>The loop <code>for i := range c</code> receives values from the channel |
| repeatedly until it is closed. |
| |
| <p>Note: Only the sender should close a channel, never the receiver. |
| <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 send or |
| receive 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: |
| return |
| } |
| } |
| } |
| |
| func main() { |
| c, quit := make(chan int), make(chan int) |
| go fibonacci(c, quit) |
| for i := 0; i < 10; i++ { |
| fmt.Println(<-c) |
| } |
| quit <- 0 |
| } |
| </div> |
| </div> |
| |
| <div class="slide"> |
| <h2>Default Selection</h2> |
| |
| <p>A <code>default</code> case in a <code>select</code> can always run. |
| |
| <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> |
| |
| <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"> |
| <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="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(2))</code> should return true, and |
| <code>Same(tree.New(1), tree.New(2))</code> should return false. |
| |
| <div> |
| package main |
| |
| import "go-tour.googlecode.com/hg/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>Where to Go from here...</h2> |
| <p> |
| The <a href="http://golang.org/doc/docs.html">Go Documentation</a> is |
| a great place to start. It contains references, tutorials, videos, and more. |
| <p> |
| If you need help with the standard library, |
| see the <a href="http://golang.org/pkg/">package reference</a>. |
| For help with the language itself, you might be surprised to find the |
| <a 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 href="http://golang.org/doc/codelab/wiki/">Wiki Codelab</a>. |
| <p> |
| If you want to further explore Go's concurrency model, see the |
| <a href="http://golang.org/doc/codewalk/sharemem/">Share Memory by Communicating</a> |
| codewalk. |
| <p> |
| The <a 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 href="http://blog.golang.org/">Go Blog</a> has a large archive of |
| informative Go articles. |
| <p> |
| Visit <a href="http://golang.org">golang.org</a> for more. |
| </div> |
| |
| </div><!-- end slides --> |
| |
| </body> |
| </html> |