/static/index.html
HTML | 2323 lines | 1986 code | 329 blank | 8 comment | 0 complexity | e6160f3d6dac728a3d2d7c04f0c4bf3b MD5 | raw file
1<html> 2<head> 3<meta http-equiv="Content-Type" content="text/html;charset=utf-8" > 4<title>Un Tour nel Go</title> 5 6<!-- jQuery --> 7<script src="static/jquery.js"></script> 8 9<!-- Fonts --> 10<link href='http://fonts.googleapis.com/css?family=Droid+Serif&v1' rel='stylesheet' type='text/css'> 11<link href='http://fonts.googleapis.com/css?family=Droid+Sans&v1' rel='stylesheet' type='text/css'> 12<link href='http://fonts.googleapis.com/css?family=Droid+Sans+Mono&v1' rel='stylesheet' type='text/css'> 13 14<!-- Playground --> 15<link rel="stylesheet" href="/static/codemirror/lib/codemirror.css"> 16<script src="/static/codemirror/lib/codemirror.js"></script> 17<link rel="stylesheet" href="/static/codemirror/theme/default.css"> 18<script src="static/playground.js"></script> 19 20<!-- Tour --> 21<link rel="stylesheet" href="static/tour.css" charset="utf-8"> 22<script src="static/mode.js"></script> 23<script src="static/tour.js"></script> 24 25</head> 26<body class="loading"> 27 28<!-- Top bar --> 29<h2 id="slidenum"></h2> 30<div id="topnav" class="nav"> 31 <button id="tocbtn">Indice</button> 32 <button id="codetr">Correggi*</button> 33</div> 34<h1>Un Tour nel Go (traduzione: 30%)</h1> 35 36<!-- Loading message --> 37<div id="loading"> 38 Caricamento schede... 39</div> 40 41<!-- Table of Contents --> 42<ol id="toc"></ol> 43 44<div id="slides" class="slides"><!-- begin slides --> 45 46<div class="toc">Benvenuto</div> 47 48<div class="slide"> 49 <h2>Ciao, 世界</h2> 50 <p> 51 Benvenuto nel tour del 52 <a target="_blank" href="http://golang.org/">Linguaggio di Programmazione Go</a>. 53 <p> 54 Il tour è diviso in tre sezioni. Alla fine di ogni sezione 55 c'è una serie di esercizi da svolgere. 56 <p> 57 Il tour è interattivo. Clicca su Run (o premi Shift-Invio) 58 per compilare e avviare il programma sul 59 <span class="appengineMode">server remoto.</span> 60 <span class="localMode">tuo computer.</span> 61 Il risultato apparirà sotto il codice. 62 <p> 63 I programmi di esempio evidenziano i diversi aspetti di Go. 64 I programmi nel tour sono punti di partenza per le tue sperimentazioni. 65 <p> 66 Modifica il programma e avvialo ancora. 67 <p> 68 Quando credi di essere pronto, clicca su Next o premi PageDown (Pag Giù). 69<div> 70package main 71 72import "fmt" 73 74func main() { 75 fmt.Println("Ciao, 世界") 76} 77</div> 78</div> 79 80<div class="slide nocode appengineMode"> 81 <h2>Go offline</h2> 82 <p> 83 Questo tour è disponibile anche come programma indipendente, 84 usabile senza connessione a internet. 85 <p> 86 Il tour offline è più veloce nell'avviare e gestire il codice di esempio 87 e include esercizi che non sono disponibili nella versione online. 88 <p> 89 Prima di avviare il tour in locale 90 <a target="_blank" href="http://golang.org/doc/install.html">installa Go</a> (l'ultima release, <code>release.r60</code>), 91 quindi usa 92 <a target="_blank" href="http://golang.org/cmd/goinstall/">goinstall</a> 93 per installare 94 <a target="_blank" href="http://code.google.com/p/go-tour/">gotour</a>: 95 <pre> goinstall go-tour.googlecode.com/hg/gotour</pre> 96 <p> 97 e avvia l'eseguibile <code>gotour</code>. 98 <p> 99 Altrimenti, fai clic sul pulsante "Next" o premi PagGiù per continuare. 100 <p> 101 <i>(Puoi tornare a queste istruzioni in qualsiasi momento facendo clic sul pulsante "Indice")</i> 102</div> 103 104<div class="slide nocode appengineMode"> 105 <h2>Go nella tua lingua</h2> 106 <p> 107 Il tour è disponibile in altre lingue: 108 <ul> 109 <li><a href="http://go-tour-jp.appspot.com/">Giapponese — 日本語</a></li> 110 <li><a href="http://go-tour-kr.appspot.com/">Coreano — 한국어</a></li> 111 <li><a href="http://go-tour-it.appspot.com/">Italiano</a> 112 <a href="http://code.google.com/p/go-tour-it/source/browse/static/index.html">(contribuisci)</a> 113 </li> 114 </ul> 115 <p> 116 (Se si desidera tradurre il tour in un'altra lingua, basta scaricare i sorgenti da<br> 117 <code>https://go-tour.googlecode.com/hg</code>, tradurre <code>static/index.html</code> e 118 distribuirlo su App Engine utilizzando le istruzioni nel file <code>appengine/README</code>.) 119 <p> 120 Fare clic sul pulsante "Next" o PagGiù per continuare. 121</div> 122 123<div class="toc">Introduzione</div> 124 125<div class="slide"> 126 <h2>Packages (Pacchetti)</h2> 127 <p> 128 Ogni programma Go è costituito da Pacchetti. 129 <p> 130 I programmi iniziano a caricarsi dal pacchetto <code>main</code>. 131 <p> 132 Questo programma utilizza i pacchetti <code>"fmt"</code> e <code>"math"</code> 133 infatti sono nel percorso di importazione. 134 <p> 135 Per convenzione, il nome del pacchetto è lo stesso dell'ultimo 136 elemento del percorso di importazione.(?) 137<div> 138package main 139 140import ( 141 "fmt" 142 "math" 143) 144 145func main() { 146 fmt.Println("Buon", math.Pi, "day") 147} 148</div> 149</div> 150 151<div class="slide"> 152 <h2>Imports</h2> 153 <p> 154 Questo codice raggruppa gli Imports in una parentesi, il metodo di importazione "scomposto". 155 Si possono anche scrivere più istruzioni import, come: 156 <pre> 157 import "fmt" 158 import "math" 159 </pre> 160 ma è di comune utilizzo il metodo "scomposto" per eliminare il disordine. 161<div> 162package main 163 164import ( 165 "fmt" 166 "math" 167) 168 169func main() { 170 fmt.Printf("Adesso hai %g problemi.", 171 math.Nextafter(2, 3)) 172} 173</div> 174</div> 175 176<div class="slide"> 177 <h2>Exported Names</h2> 178 <p> 179 Dopo aver importato un pacchetto, è possibile fare riferimento ai suoi nomi. 180 <p> 181 In Go, un nome viene esportato se inizia con la lettera maiuscola. 182 <p> 183 <code>Pi</code> è un nome esportato, come <code>PI</code>. 184 Il nome <code>pi</code> non è esportato. 185 <p> 186 Esegui il codice. Quindi rinomina <code>math.pi</code> in <code>math.Pi</code> e riprova. 187<div> 188package main 189 190import ( 191 "fmt" 192 "math" 193) 194 195func main() { 196 fmt.Println(math.pi) 197} 198</div> 199</div> 200 201<div class="slide"> 202 <h2>Funzioni</h2> 203 <p> 204 Una funzione può assumere zero o più argomenti. 205 <p> 206 In questo esempio, <code>add</code> accetta due parametri di tipo <code>int</code>. 207 <p> 208 Si noti che il tipo viene <i>dopo</i> il nome della variabile. 209 <p> 210 (Per maggiori informazioni sul funzionamento dei tipi, si veda questo <a target="_blank" href="http://blog.golang.org/2010/07/gos-declaration-syntax.html">post del blog</a>) 211 212<div> 213package main 214 215import "fmt" 216 217func add(x int, y int) int { 218 return x + y 219} 220 221func main() { 222 fmt.Println(add(42, 13)) 223} 224</div> 225</div> 226 227<div class="slide"> 228 <h2>Funzioni</h2> 229 <p> 230 Quando due o più nomi consecutivi condividono il tipo, 231 è possibile omettere il tipo da tutti tranne l'ultimo. 232 <p> 233 In questo esempio, abbiamo accorciato 234 <pre>x int, y int</pre> 235 <p> 236 in 237 <pre>x, y int</pre> 238<div> 239package main 240 241import "fmt" 242 243func add(x, y int) int { 244 return x + y 245} 246 247func main() { 248 fmt.Println(add(42, 13)) 249} 250</div> 251</div> 252 253<div class="slide"> 254 <h2>Funzioni</h2> 255 <p> 256 Una funzione può restituire qualsiasi numero di risultati. 257 <p> 258 Questa funzione restituisce due stringhe. 259<div> 260package main 261 262import "fmt" 263 264func swap(x, y string) (string, string) { 265 return y, x 266} 267 268func main() { 269 a, b := swap("ciao", "mondo") 270 fmt.Println(a, b) 271} 272</div> 273</div> 274 275<div class="slide"> 276 <h2>Funzioni</h2> 277 <p> 278 Le funzioni prendono parametri; in Go i risultati possono essere nominati e 279 si comportano come variabili; questi sono chiamati "result parameters". 280 <p> 281 Se i "result parameters" sono stati nominati, un <code>return</code> senza argomenti 282 restituisce i valori correnti dei risultati. 283<div> 284package main 285 286import "fmt" 287 288func split(sum int) (x, y int) { 289 x = sum * 4/9 290 y = sum - x 291 return 292} 293 294func main() { 295 fmt.Println(split(17)) 296} 297</div> 298</div> 299 300<div class="slide"> 301 <h2>Variabili</h2> 302 <p> 303 L' istruzione <code>var</code> dichiara una lista di variabili.<br> 304 Come negli elenchi di argomenti delle funzioni, il tipo è alla fine. 305<div> 306package main 307 308import "fmt" 309 310var x, y, z int 311var c, python, java bool 312 313func main() { 314 fmt.Println(x, y, z, c, python, java) 315} 316</div> 317</div> 318 319<div class="slide"> 320 <h2>Variabili</h2> 321 <p> 322 Una dichiarazione var può includere gli inizializzatori, uno per ogni variabile. 323 <p> 324 Se un initializer è presente, il tipo può essere omesso; 325 la variabile prenderà il tipo dell' inizializer. 326<div> 327package main 328 329import "fmt" 330 331var x, y, z int = 1, 2, 3 332var c, python, java = true, false, "no!" 333 334func main() { 335 fmt.Println(x, y, z, c, python, java) 336} 337</div> 338</div> 339 340<div class="slide"> 341 <h2>Variabili</h2> 342 <p> 343 All'interno di una funzione, l'istruzione di assegnazione breve <code>:=</code> 344 può essere usata al posto della dichiarazione breve <code>var</code>. 345 <p> 346 (Al di fuori di una funzione, ogni costrutto inizia con una 347 parola chiave mentre l'istruzione := non è disponibile). 348<div> 349package main 350 351import "fmt" 352 353func main() { 354 var x, y, z int = 1, 2, 3 355 c, python, java := true, false, "no!" 356 357 fmt.Println(x, y, z, c, python, java) 358} 359</div> 360</div> 361 362<div class="slide"> 363 <h2>Constanti</h2> 364 <p> 365 Le constanti vengono dichiarate come le variabili, ma con la parola-chiave <code>const</code>. 366 <p> 367 Le costanti possono essere stringhe, boolean o valori numerici. 368<div> 369package main 370 371import "fmt" 372 373const Pi = 3.14 374 375func main() { 376 const World = "世界" 377 fmt.Println("Hello", World) 378 fmt.Println("Happy", Pi, "Day") 379 380 const Truth = true 381 fmt.Println("Go rules?", Truth) 382} 383</div> 384</div> 385 386<div class="slide"> 387 <h2>Costanti numeriche</h2> 388 <p> 389 Le costanti numeriche sono <i>valori</i> ad alta precisione. 390 <p> 391 Una costante senza tipo prende il tipo necessario dal suo contesto. 392 <p> 393 Prova a stampare anche <code>needInt(Big)</code>. 394<div> 395package main 396 397import "fmt" 398 399const ( 400 Big = 1<<100 401 Small = Big>>99 402) 403 404func needInt(x int) int { return x*10 + 1 } 405func needFloat(x float64) float64 { 406 return x*0.1 407} 408 409func main() { 410 fmt.Println(needInt(Small)) 411 fmt.Println(needFloat(Small)) 412 fmt.Println(needFloat(Big)) 413} 414</div> 415</div> 416 417<div class="slide"> 418 <h2>For</h2> 419 <p> 420 Go ha solo un costrutto per le operazioni cicliche:<br> 421 il ciclo <code>for</code>. 422 <p> 423 Il ciclo <code>for</code> appare come in C o Java, salvo che 424 le parentesi tonde <code>( )</code> non esistono (non sono 425 nemmeno opzionali) mentre le graffe <code>{ }</code> sono obbligatorie. 426<div> 427package main 428 429import "fmt" 430 431func main() { 432 sum := 0 433 for i := 0; i < 10; i++ { 434 sum += i 435 } 436 fmt.Println(sum) 437} 438</div> 439</div> 440 441<div class="slide"> 442 <h2>For</h2> 443 <p> 444 Come in C o Java, è possibile lasciare le dichiarazioni pre e post vuote. 445<div> 446package main 447 448import "fmt" 449 450func main() { 451 sum := 1 452 for ; sum < 1000; { 453 sum += sum 454 } 455 fmt.Println(sum) 456} 457</div> 458</div> 459 460<div class="slide"> 461 <h2>For</h2> 462 <p> 463 A questo punto è possibile eliminare i punti-virgola: 464 Per ottenere ciò che in C avremmo scritto <code>while</code> in Go scriviamo <code>for</code>. 465<div> 466package main 467 468import "fmt" 469 470func main() { 471 sum := 1 472 for sum < 1000 { 473 sum += sum 474 } 475 fmt.Println(sum) 476} 477</div> 478</div> 479 480<div class="slide"> 481 <h2>For</h2> 482 <p> 483 Se si omette la condizione del ciclo, il ciclo continua per sempre. 484<div> 485package main 486 487func main() { 488 for ; ; { 489 } 490} 491</div> 492</div> 493 494<div class="slide"> 495 <h2>For</h2> 496 <p> 497 E senza condizioni, i punti-virgola possono essere omessi. 498 Ecco come appare un ciclo infinito compatto. 499<div> 500package main 501 502func main() { 503 for { 504 } 505} 506</div> 507</div> 508 509<div class="slide"> 510 <h2>If</h2> 511 <p> 512 L'istruzione <code>if</code> è si comporta come in C o Java, 513 salvo che le parentesi tonde <code>( )</code> non esistono (non sono nemmeno opzionali) 514 e le graffe <code>{ }</code> sono obbligatorie. 515 <p> 516 (Ti ricorda qualcosa?) 517<div> 518package main 519 520import ( 521 "fmt" 522 "math" 523) 524 525func sqrt(x float64) string { 526 if x < 0 { 527 return sqrt(-x) + "i" 528 } 529 return fmt.Sprint(math.Sqrt(x)) 530} 531 532func main() { 533 fmt.Println(sqrt(2), sqrt(-4)) 534} 535</div> 536</div> 537 538<div class="slide"> 539 <h2>If</h2> 540 <p> 541 Come <code>for</code>, l'istruzione <code>if</code> può iniziare 542 con una breve dichiarazione da eseguire prima della condizione. 543 <p> 544 Le variabili dichiarate dalla dichiarazione sono disponibili solo fino alla fine del <code>if</code>. 545 <p> 546 (Prova ad usare <code>v</code> nell'ultima istruzione <code>return</code>.) 547<div> 548package main 549 550import ( 551 "fmt" 552 "math" 553) 554 555func pow(x, n, lim float64) float64 { 556 if v := math.Pow(x, n); v < lim { 557 return v 558 } 559 return lim 560} 561 562func main() { 563 fmt.Println( 564 pow(3, 2, 10), 565 pow(3, 3, 20), 566 ) 567} 568</div> 569</div> 570 571<div class="slide"> 572 <h2>If</h2> 573 <p> 574 Le variabili dichiarate all'interno di una istruzione <code>if</code> 575 sono disponibili anche in una qualsiasi dei blocchi <code>else</code>. 576<div> 577package main 578 579import ( 580 "fmt" 581 "math" 582) 583 584func pow(x, n, lim float64) float64 { 585 if v := math.Pow(x, n); v < lim { 586 return v 587 } else { 588 fmt.Printf("%g >= %g\n", v, lim) 589 } 590 // can't use v here, though 591 return lim 592} 593 594func main() { 595 fmt.Println( 596 pow(3, 2, 10), 597 pow(3, 3, 20), 598 ) 599} 600</div> 601</div> 602 603<div class="slide"> 604 <h2>Tipi di base</h2> 605 <p> 606 I tipi di base di Go sono: 607 <pre> 608bool 609 610string 611 612int int8 int16 int32 int64 613uint uint8 uint16 uint32 uint64 uintptr 614 615float32 float64 616 617complex64 complex128 618 </pre> 619<div> 620package main 621 622import ( 623 "cmath" 624 "fmt" 625) 626 627var ( 628 ToBe bool = false 629 MaxInt uint64 = 1<<64 - 1 630 z complex128 = cmath.Sqrt(-5+12i) 631) 632 633func main() { 634 const f = "%T(%v)\n" 635 fmt.Printf(f, ToBe, ToBe) 636 fmt.Printf(f, MaxInt, MaxInt) 637 fmt.Printf(f, z, z) 638} 639</div> 640</div> 641 642<div class="slide"> 643 <h2>Structs (strutture)</h2> 644 <p> 645 Una <code>struct</code> è un insieme di campi. 646 <p> 647 (E le dichiarazioni <code>type</code> si comportano come vi aspettereste.) 648<div> 649package main 650 651import "fmt" 652 653type Vertex struct { 654 X int 655 Y int 656} 657 658func main() { 659 fmt.Println(Vertex{1, 2}) 660} 661</div> 662</div> 663 664<div class="slide"> 665 <h2>Struct Fields (Campi Struttura)</h2> 666 <p> 667 Un Struct field è accessibile tramite un punto. 668<div> 669package main 670 671import "fmt" 672 673type Vertex struct { 674 X int 675 Y int 676} 677 678func main() { 679 v := Vertex{1, 2} 680 v.X = 4 681 fmt.Println(v.X) 682} 683</div> 684</div> 685 686<div class="slide"> 687 <h2>Pointers (Puntatori)</h2> 688 <p> 689 Go utilizza i puntatori, ma non l'aritmetica dei puntatori. 690 <p> 691 I campi struct sono accessibili tramite puntatori struct.<br> 692 L'indirezione attraverso il puntatore è trasparente. 693<div> 694package main 695 696import "fmt" 697 698type Vertex struct { 699 X int 700 Y int 701} 702 703func main() { 704 p := Vertex{1, 2} 705 q := &p 706 q.X = 1e9 707 fmt.Println(p) 708} 709</div> 710</div> 711 712<div class="slide"> 713 <h2>Struct Literals (letterali)</h2> 714 <p> 715 Una struttura letterale denota un valore struct appena allocato elencando i valori dei suoi campi. 716 <p> 717 Si possono elencare solo un sottoinsieme di campi utilizzando la sintassi <code>Name:</code>. 718 (L'ordine dei campi di nome è irrilevante) 719 <p> 720 Il prefisso specifico <code>&</code> costituisce un puntatore ad una struct letterale. 721<div> 722package main 723 724import "fmt" 725 726type Vertex struct { 727 X, Y int 728} 729 730var ( 731 p = Vertex{1, 2} // has type Vertex 732 q = &Vertex{1, 2} // has type *Vertex 733 r = Vertex{X: 1} // Y:0 is implicit 734 s = Vertex{} // X:0 and Y:0 735) 736 737func main() { 738 fmt.Println(p, q, r, s) 739} 740</div> 741</div> 742 743<div class="slide"> 744 <h2>La funzione <code>new</code></h2> 745 <p> 746 L'espressione new(T) alloca un valore T azzerato e restituisce un puntatore ad esso. 747 <pre>var t *T = new(T)</pre> 748 <p> 749 oppure 750 <pre>t := new(T)</pre> 751<div> 752package main 753 754import "fmt" 755 756type Vertex struct { 757 X, Y int 758} 759 760func main() { 761 v := new(Vertex) 762 fmt.Println(v) 763 v.X, v.Y = 11, 9 764 fmt.Println(v) 765} 766</div> 767</div> 768 769<div class="slide"> 770 <h2>Maps (Mappe)</h2> 771 <p> 772 Una map mappa (verbo mappare) chiavi per i valori. 773 <p> 774 <!-- TODO: empty part not true in compilers yet --> 775 Le mappe devono essere creati con <code>make</code> (non <code>new</code>) prima dell'uso; 776 il <code>nil</code> map è vuoto e non può essere assegnato. 777<div> 778package main 779 780import "fmt" 781 782type Vertex struct { 783 Lat, Long float64 784} 785 786var m map[string]Vertex 787 788func main() { 789 m = make(map[string]Vertex) 790 m["Bell Labs"] = Vertex{ 791 40.68433, 74.39967, 792 } 793 fmt.Println(m["Bell Labs"]) 794} 795</div> 796</div> 797 798<div class="slide"> 799 <h2>Maps (letterali)</h2> 800 <p> 801 Map literals sono come le strutture letterali, ma le chiavi sono obbligatore. 802<div> 803package main 804 805import "fmt" 806 807type Vertex struct { 808 Lat, Long float64 809} 810 811var m = map[string]Vertex{ 812 "Bell Labs": Vertex{ 813 40.68433, -74.39967, 814 }, 815 "Google": Vertex{ 816 37.42202, -122.08408, 817 }, 818} 819 820func main() { 821 fmt.Println(m) 822} 823</div> 824</div> 825 826<div class="slide"> 827 <h2>Maps</h2> 828 <p> 829 Se il tipo primcipale è solo un nome del tipo, 830 è possibile omettere dagli elementi del letterale. 831<div> 832package main 833 834import "fmt" 835 836type Vertex struct { 837 Lat, Long float64 838} 839 840var m = map[string]Vertex{ 841 "Bell Labs": {40.68433, -74.39967}, 842 "Google": {37.42202, -122.08408}, 843} 844 845func main() { 846 fmt.Println(m) 847} 848</div> 849</div> 850 851<div class="slide"> 852 <h2>Slices (Porzioni)</h2> 853 <p> 854 Una slice punta a un array di valori e comprende anche una lunghezza. 855 <p> 856 <code>[]T</code> è una slice con elementi del tipo <code>T</code>. 857<div> 858package main 859 860import "fmt" 861 862func main() { 863 p := []int{2, 3, 5, 7, 11, 13} 864 fmt.Println("p ==", p) 865 866 for i := 0; i < len(p); i++ { 867 fmt.Printf("p[%d] == %d\n", 868 i, p[i]) 869 } 870} 871</div> 872</div> 873 874<div class="slide"> 875 <h2>Slices</h2> 876 <p> 877 Le Slices possono essere ripartite a loro volta, la creazione di un nuovo 878 valore slice che punta allo stesso array. 879 <p> 880 L'espressione 881 <pre>s[lo:hi]</pre> 882 <p> 883 restituisce una slice di elementi da <code>lo</code> attraverso <code>hi-1</code>, estremi inclusi. 884 In questo modo, 885 <pre>s[lo:lo]</pre> 886 <p> 887 è vuota e 888 <pre>s[lo:lo+1]</pre> 889 <p> 890 ha un valore. 891<div> 892package main 893 894import "fmt" 895 896func main() { 897 p := []int{2, 3, 5, 7, 11, 13} 898 fmt.Println("p ==", p) 899 fmt.Println("p[1:4] ==", p[1:4]) 900 901// l'assenza dell' indice basso implica 0 902 fmt.Println("p[:3] ==", p[:3]) 903 904// l'assenza dell' indice alto implica len(s) 905 fmt.Println("p[4:] ==", p[4:]) 906} 907</div> 908</div> 909 910<div class="slide"> 911 <h2>Slices</h2> 912 <p> 913 Le Slices si creano con la funzione <code>make</code>. Funziona allocando 914 un array azzerato e restituendo una slice che fa riferimento a tale array: 915 <pre> 916a := make([]int, 5) // len(a)=5 917 </pre> 918 Le Slices hanno lunghezza (len) e capacità (cap). La capacità di una slice è 919 la lunghezza massima che la slice può raggiungere all'interno dell' array sottostante. 920 <p> 921 Per specificare una capacità, basta passare un terzo argomento a <code>make</code>: 922 <p> 923 <pre> 924b := make([]int, 0, 5) 925// len(b)=0, cap(b)=5 926 </pre> 927 Le Slices possono essere alimentate dal "re-slicing" (fino alla loro capacità): 928 <p> 929 <pre> 930b = b[:cap(b)] // len(b)=5, cap(b)=5 931b = b[1:] // len(b)=4, cap(b)=4 932 </pre> 933<div> 934package main 935 936import "fmt" 937 938func main() { 939 a := make([]int, 5) 940 printSlice("a", a) 941 b := make([]int, 0, 5) 942 printSlice("b", b) 943 c := b[:2] 944 printSlice("c", c) 945 d := c[2:5] 946 printSlice("d", d) 947} 948 949func printSlice(s string, x []int) { 950 fmt.Printf("%s len=%d cap=%d %v\n", 951 s, len(x), cap(x), x) 952} 953</div> 954</div> 955 956<div class="slide"> 957 <h2>Slices</h2> 958 <p> 959 The zero value of a slice is <code>nil</code>. 960 <p> 961 A nil slice has a length and capacity of 0. 962 <p> 963 <i>For more detail see the 964 "<a target="_blank" href="http://blog.golang.org/2011/01/go-slices-usage-and-internals.html">Go Slices: usage and internals</a>" 965 article.</i> 966<div> 967package main 968 969import "fmt" 970 971func main() { 972 var z []int 973 fmt.Println(z, len(z), cap(z)) 974 if z == nil { 975 fmt.Println("nil!") 976 } 977} 978</div> 979</div> 980 981<div class="slide"> 982 <h2>Functions</h2> 983 <p> 984 Functions are values too. 985<div> 986package main 987 988import ( 989 "fmt" 990 "math" 991) 992 993func main() { 994 hypot := func(x, y float64) float64 { 995 return math.Sqrt(x*x + y*y) 996 } 997 998 fmt.Println(hypot(3, 4)) 999} 1000</div> 1001</div> 1002 1003<div class="slide"> 1004 <h2>Functions</h2> 1005 <p> 1006 And functions are full closures. 1007 <p> 1008 The <code>adder</code> function returns a closure. 1009 Each closure is bound to its own <code>sum</code> variable. 1010<div> 1011package main 1012 1013import "fmt" 1014 1015func adder() func(int) int { 1016 sum := 0 1017 return func(x int) int { 1018 sum += x 1019 return sum 1020 } 1021} 1022 1023func main() { 1024 pos, neg := adder(), adder() 1025 for i := 0; i < 10; i++ { 1026 fmt.Println( 1027 pos(i), 1028 neg(-2*i), 1029 ) 1030 } 1031} 1032</div> 1033</div> 1034 1035<div class="slide"> 1036 <h2>Range</h2> 1037 <p> 1038 The <code>range</code> form of the <code>for</code> 1039 loop iterates over a slice or map. 1040<div> 1041package main 1042 1043import "fmt" 1044 1045var pow = []int{1, 2, 4, 8, 16, 32, 64, 128} 1046 1047func main() { 1048 for i, v := range pow { 1049 fmt.Printf("2**%d = %d\n", i, v) 1050 } 1051} 1052</div> 1053</div> 1054 1055<div class="slide"> 1056 <h2>Range</h2> 1057 <p> 1058 You can skip the key or value by assigning to <code>_</code>. 1059 <p> 1060 If you only want the index, drop the 1061 “<code>, value</code>” entirely. 1062<div> 1063package main 1064 1065import "fmt" 1066 1067func main() { 1068 pow := make([]int, 10) 1069 for i := range pow { 1070 pow[i] = 1<<uint(i) 1071 } 1072 for _, value := range pow { 1073 fmt.Printf("%d\n", value) 1074 } 1075} 1076</div> 1077</div> 1078 1079<div class="slide"> 1080 <h2>Switch</h2> 1081 <p> 1082 You probably knew what <code>switch</code> was going to look like. 1083 <p> 1084 A case body breaks automatically, unless it ends with a <code>fallthrough</code> statement. 1085 1086<div> 1087package main 1088 1089import ( 1090 "fmt" 1091 "runtime" 1092) 1093 1094func main() { 1095 fmt.Print("Go runs on ") 1096 switch os := runtime.GOOS; os { 1097 case "darwin": 1098 fmt.Println("OS X.") 1099 case "linux": 1100 fmt.Println("Linux.") 1101 default: 1102 // freebsd, openbsd, 1103 // plan9, windows... 1104 fmt.Printf("%s.", os) 1105 } 1106} 1107</div> 1108</div> 1109 1110<div class="slide"> 1111 <h2>Switch</h2> 1112 <p> 1113 Switch cases evaluate cases from top to bottom, stopping when a 1114 case succeeds. 1115 <p> 1116 (For example, 1117 <pre> 1118switch i { 1119case 0: 1120case f(): 1121}</pre> 1122 <p> 1123 does not call <code>f</code> if <code>i==0</code>.) 1124 1125<div> 1126package main 1127 1128import ( 1129 "fmt" 1130 "time" 1131) 1132 1133func main() { 1134 fmt.Println("When's Saturday?") 1135 today := time.LocalTime().Weekday 1136 switch time.Saturday { 1137 case today+0: 1138 fmt.Println("Today.") 1139 case today+1: 1140 fmt.Println("Tomorrow.") 1141 case today+2: 1142 fmt.Println("In two days.") 1143 default: 1144 fmt.Println("Too far away.") 1145 } 1146} 1147</div> 1148</div> 1149 1150<div class="slide"> 1151 <h2>Switch</h2> 1152 <p> 1153 Switch without a condition is the same as <code>switch true</code>. 1154 1155<div> 1156package main 1157 1158import ( 1159 "fmt" 1160 "time" 1161) 1162 1163func main() { 1164 t := time.LocalTime() 1165 switch { 1166 case t.Hour < 12: 1167 fmt.Println("Good morning!") 1168 case t.Hour < 17: 1169 fmt.Println("Good afternoon.") 1170 default: 1171 fmt.Println("Good evening.") 1172 } 1173} 1174</div> 1175</div> 1176 1177<div class="slide"> 1178 <h2>Exercise: Loops and Functions</h2> 1179 <p> 1180 As a simple way to play with functions and loops, implement 1181 the square root function using Newton's method. 1182 <p> 1183 In this case, Newton's method is to approximate <code>Sqrt(x)</code> 1184 by picking a starting point <i>z</i> and then repeating: 1185 <center> 1186 <img src="https://chart.googleapis.com/chart?cht=tx&chl=z=z-\frac{z^2-x}{2z}"> 1187 </center> 1188 <p> 1189 To begin with, just repeat that calculation 10 times and see how close you 1190 get to the answer for various values (1, 2, 3, ...). 1191 <p> 1192 Next, change the loop condition to stop once the value has stopped 1193 changing (or only changes by a very small delta). 1194 See if that's more or fewer iterations. 1195 How close are you to the <a target="_blank" href="http://golang.org/pkg/math/#Sqrt">math.Sqrt</a>? 1196 <p> 1197 Hint: to declare and initialize a floating point value, give it 1198 floating point syntax or use a conversion: 1199 <pre> 1200 z := float64(0) 1201 z := 0.0 1202 </pre> 1203 1204<div> 1205package main 1206 1207import ( 1208 "fmt" 1209) 1210 1211func Sqrt(x float64) float64 { 1212} 1213 1214func main() { 1215 fmt.Println(Sqrt(2)) 1216} 1217</div> 1218</div> 1219 1220<div class="slide"> 1221 <h2>Exercise: Maps</h2> 1222 <p> 1223 Implement <code>WordCount</code>. It should return a map of the 1224 counts of each “word” in the string <code>s</code>. 1225 The <code>wc.Test</code> function runs a test suite against the 1226 provided function and prints success or failure. 1227 <p> 1228 You might find <a target="_blank" href="http://golang.org/pkg/strings/#Fields">strings.Fields</a> helpful. 1229 1230<div> 1231package main 1232 1233import ( 1234 "<span class="appengineMode">tour</span><span class="localMode">go-tour.googlecode.com/hg</span>/wc" 1235) 1236 1237func WordCount(s string) map[string]int { 1238 return map[string]int{"x": 1} 1239} 1240 1241func main() { 1242 wc.Test(WordCount) 1243} 1244</div> 1245</div> 1246 1247<div class="slide"> 1248 <h2>Exercise: Slices</h2> 1249 <p> 1250 Implement <code>Pic</code>. It should return a slice of length 1251 <code>dy</code>, each element of which is a slice of <code>dx</code> 1252 8-bit unsigned integers. When you run the program, it will display 1253 your picture, interpreting the integers as grayscale (well, bluescale) 1254 values. 1255 <p> 1256 The choice of image is up to you. 1257 Interesting functions include <code>x^y</code>, <code>(x+y)/2</code>, and <code>x*y</code>. 1258 <p> 1259 (You need to use a loop to allocate each <code>[]uint8</code> inside 1260 the <code>[][]uint8</code>.) 1261 1262<div> 1263package main 1264 1265import "<span class="appengineMode">tour</span><span class="localMode">go-tour.googlecode.com/hg</span>/pic" 1266 1267func Pic(dx, dy int) [][]uint8 { 1268} 1269 1270func main() { 1271 pic.Show(Pic) 1272} 1273</div> 1274</div> 1275 1276<div class="slide"> 1277 <h2>Exercise: Fibonacci closure</h2> 1278 <p> 1279 Let's have some fun with functions. 1280 <p> 1281 Implement a <code>fibonacci</code> function that returns a function 1282 (a closure) that returns successive fibonacci numbers. 1283 1284<div> 1285package main 1286 1287import "fmt" 1288 1289// fibonacci is a function that returns 1290// a function that returns an int. 1291func fibonacci() func() int { 1292} 1293 1294func main() { 1295 f := fibonacci() 1296 for i := 0; i < 10; i++ { 1297 fmt.Println(f()) 1298 } 1299} 1300</div> 1301</div> 1302 1303<div class="slide"> 1304 <h2>Advanced Exercise: Complex cube roots</h2> 1305 <p> 1306 Let's explore Go's built-in support for complex numbers via the 1307 <code>complex64</code> and <code>complex128</code> types. 1308 For cube roots, Newton's method amounts to repeating: 1309 <center> 1310 <img src="https://chart.googleapis.com/chart?cht=tx&chl=z=z-\frac{z^3-x}{3z^2}"> 1311 </center> 1312 <p> 1313 Find the cube root of 2, just to make sure the algorithm works. 1314 There is a <a target="_blank" href="http://golang.org/pkg/cmath/#Pow">cmath.Pow</a> function. 1315 1316<div> 1317package main 1318 1319import "fmt" 1320 1321func Cbrt(x complex128) complex128 { 1322} 1323 1324func main() { 1325 fmt.Println(Cbrt(2)) 1326} 1327</div> 1328</div> 1329 1330 1331<div class="toc">Methods and Interfaces</div> 1332 1333<div class="slide nocode"> 1334<h2>Methods and Interfaces</h2> 1335</div> 1336 1337<div class="slide"> 1338 <h2>Methods</h2> 1339 <p> 1340 Go does not have classes. However, you can define methods on struct 1341 types. 1342 <p> 1343 The <i>method receiver</i> appears in its own argument list 1344 between the <code>func</code> keyword and the method name. 1345<div> 1346package main 1347 1348import ( 1349 "fmt" 1350 "math" 1351) 1352 1353type Vertex struct { 1354 X, Y float64 1355} 1356 1357func (v *Vertex) Abs() float64 { 1358 return math.Sqrt(v.X*v.X + v.Y*v.Y) 1359} 1360 1361func main() { 1362 v := &Vertex{3, 4} 1363 fmt.Println(v.Abs()) 1364} 1365</div> 1366</div> 1367 1368<div class="slide"> 1369 <h2>Methods</h2> 1370 <p> 1371 In fact, you can define a method on <i>any</i> type you define in your 1372 package, not just structs. 1373 <p> 1374 You cannot define a method on a type from another package, or on a 1375 basic type. 1376<div> 1377package main 1378 1379import ( 1380 "fmt" 1381 "math" 1382) 1383 1384type MyFloat float64 1385 1386func (f MyFloat) Abs() float64 { 1387 if f < 0 { 1388 return float64(-f) 1389 } 1390 return float64(f) 1391} 1392 1393func main() { 1394 f := MyFloat(-math.Sqrt2) 1395 fmt.Println(f.Abs()) 1396} 1397</div> 1398</div> 1399 1400<div class="slide"> 1401 <h2>Methods with pointer receivers</h2> 1402 <p> 1403 Methods can be associated with a named type or a pointer 1404 to a named type. 1405 <p> 1406 We just saw two <code>Abs</code> methods. One on the 1407 <code>*Vertex</code> pointer type and the other on the 1408 <code>MyFloat</code> value type. 1409 <p> 1410 There are two reasons to use a pointer receiver. 1411 First, to avoid copying the value on each method call (more efficient 1412 if the value type is a large struct). Second, so that the method can 1413 modify the value that its receiver points to. 1414 </ol> 1415 <p> 1416 Try changing the declarations of the <code>Abs</code> and 1417 <code>Scale</code> methods to use <code>Vertex</code> as the 1418 receiver, instead of <code>*Vertex</code>. 1419 <p> 1420 The <code>Scale</code> method has no effect when <code>v</code> is a 1421 <code>Vertex</code>. <code>Scale</code> mutates <code>v</code>. When 1422 <code>v</code> is a value (non-pointer) type, the method sees a copy of 1423 the <code>Vertex</code> and cannot mutate the original value. 1424 <p> 1425 <code>Abs</code> works either way. It only reads <code>v</code>. 1426 It doesn't matter whether it is reading the original value (through a 1427 pointer) or a copy of that value. 1428<div> 1429package main 1430 1431import ( 1432 "fmt" 1433 "math" 1434) 1435 1436type Vertex struct { 1437 X, Y float64 1438} 1439 1440func (v *Vertex) Scale(f float64) { 1441 v.X = v.X * f 1442 v.Y = v.Y * f 1443} 1444 1445func (v *Vertex) Abs() float64 { 1446 return math.Sqrt(v.X*v.X + v.Y*v.Y) 1447} 1448 1449func main() { 1450 v := &Vertex{3, 4} 1451 v.Scale(5) 1452 fmt.Println(v, v.Abs()) 1453} 1454</div> 1455</div> 1456 1457<div class="slide"> 1458 <h2>Interfaces</h2> 1459 <p> 1460 An interface type is defined by a set of methods. 1461 <p> 1462 A value of interface type can hold any value that 1463 implements those methods. 1464 1465<div> 1466package main 1467 1468import ( 1469 "fmt" 1470 "math" 1471) 1472 1473type Abser interface { 1474 Abs() float64 1475} 1476 1477func main() { 1478 var a Abser 1479 f := MyFloat(-math.Sqrt2) 1480 v := Vertex{3, 4} 1481 1482 a = f // a MyFloat implements Abser 1483 a = &v // a *Vertex implements Abser 1484 a = v // a Vertex, does NOT 1485 // implement Abser 1486 1487 fmt.Println(a.Abs()) 1488} 1489 1490type MyFloat float64 1491 1492func (f MyFloat) Abs() float64 { 1493 if f < 0 { 1494 return float64(-f) 1495 } 1496 return float64(f) 1497} 1498 1499type Vertex struct { 1500 X, Y float64 1501} 1502 1503func (v *Vertex) Abs() float64 { 1504 return math.Sqrt(v.X*v.X + v.Y*v.Y) 1505} 1506</div> 1507</div> 1508 1509<div class="slide"> 1510 <h2>Interfaces</h2> 1511 <p> 1512 A type implements an interface by implementing the methods. 1513 <p> 1514 <i>There is no explicit declaration of intent.</i> 1515 <p> 1516 Implicit interfaces decouple implementation packages from the packages 1517 that define the interfaces: neither depends on the other. 1518 <p> 1519 It also encourages the definition of precise interfaces, because you 1520 don't have to find every implementation and tag it with the new 1521 interface name. 1522 <p> 1523 <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. 1524<div> 1525package main 1526 1527import ( 1528 "fmt" 1529 "os" 1530) 1531 1532type Reader interface { 1533 Read(b []byte) (n int, err os.Error) 1534} 1535 1536type Writer interface { 1537 Write(b []byte) (n int, err os.Error) 1538} 1539 1540type ReadWriter interface { 1541 Reader 1542 Writer 1543} 1544 1545func main() { 1546 var w Writer 1547 1548 // os.Stdout implements Writer 1549 w = os.Stdout 1550 1551 fmt.Fprintf(w, "hello, writer\n") 1552} 1553</div> 1554</div> 1555 1556<div class="slide"> 1557 <h2>Errors</h2> 1558 <p> 1559 An error is anything that can describe itself: 1560 <pre> 1561package os 1562 1563type Error interface { 1564 String() string 1565} 1566 </pre> 1567 1568<div> 1569package main 1570 1571import ( 1572 "fmt" 1573 "os" 1574 "time" 1575) 1576 1577type MyError struct { 1578 When *time.Time 1579 What string 1580} 1581 1582func (e *MyError) String() string { 1583 return fmt.Sprintf("at %v, %s", 1584 e.When, e.What) 1585} 1586 1587func run() os.Error { 1588 return &MyError{ 1589 time.LocalTime(), 1590 "it didn't work", 1591 } 1592} 1593 1594func main() { 1595 if err := run(); err != nil { 1596 fmt.Println(err) 1597 } 1598} 1599</div> 1600</div> 1601 1602<div class="slide"> 1603 <h2>Web servers</h2> 1604 <p> 1605 <a target="_blank" href="http://golang.org/pkg/http/">Package http</a> serves HTTP requests using any value 1606 that implements <code>http.Handler</code>: 1607 <pre> 1608package http 1609 1610type Handler interface { 1611 ServeHTTP(w ResponseWriter, 1612 r *Request) 1613} 1614 </pre> 1615 <p> 1616 In this example, the type <code>MyHandler</code> implements <code>http.Handler</code>. 1617 <p> 1618 <span class="localMode"> 1619 Visit <a href="http://localhost:4000/" target="_blank">http://localhost:4000/</a> to see the greeting. 1620 </span> 1621 <span class="appengineMode"> 1622 <b>Note:</b> This example won't run through the web-based tour user 1623 interface. To try writing web servers you may want to 1624 <a target="_blank" href="http://golang.org/doc/install.html">Install 1625 Go</a>. 1626 </span> 1627<div> 1628package main 1629 1630import ( 1631 "fmt" 1632 "http" 1633) 1634 1635type Hello struct{} 1636 1637func (h Hello) ServeHTTP( 1638 w http.ResponseWriter, 1639 r *http.Request) { 1640 fmt.Fprint(w, "Hello!") 1641} 1642 1643func main() { 1644 var h Hello 1645 http.ListenAndServe("localhost:4000",h) 1646} 1647</div> 1648</div> 1649 1650<div class="slide"> 1651 <h2>Images</h2> 1652 <p> 1653 <a target="_blank" href="http://golang.org/pkg/image/#Image">Package image</a> defines the <code>Image</code> 1654 interface: 1655 <pre> 1656package image 1657 1658type Image interface { 1659 ColorModel() ColorModel 1660 Bounds() Rectangle 1661 At(x, y int) Color 1662}</pre> 1663 <p> 1664 (See <a target="_blank" href="http://golang.org/pkg/image/#Image">the 1665 documentation</a> for all the details.) 1666 <p> 1667 <code>Color</code> and <code>ColorModel</code> are interfaces too, 1668 but we'll ignore that by using the predefined implementations 1669 <code>image.RGBAColor</code> and <code>image.RGBAColorModel</code>. 1670 1671<div> 1672package main 1673 1674import ( 1675 "fmt" 1676 "image" 1677) 1678 1679func main() { 1680 m := image.NewRGBA(100, 100) 1681 fmt.Println(m.Bounds()) 1682 fmt.Println(m.At(0, 0).RGBA()) 1683} 1684</div> 1685</div> 1686 1687<div class="slide"> 1688 <h2>Exercise: Errors</h2> 1689 <p> 1690 Copy your <code>Sqrt</code> function from the earlier exercises and 1691 modify it to return an <code>os.Error</code> value. 1692 <p> 1693 <code>Sqrt</code> should return a non-nil error value when given a 1694 negative number, as it doesn't support complex numbers. 1695 <p> 1696 Create a new type 1697 <pre> 1698type ErrNegativeSqrt float64</pre> 1699 <p> 1700 and make it an <code>os.Error</code> by giving it a 1701 <pre> 1702func (e ErrNegativeSqrt) String() string</pre> 1703 <p> 1704 method such that <code>ErrNegativeSqrt(-2).String()</code> returns 1705 <code>"cannot Sqrt negative number: -2"</code>. 1706 <p> 1707 <b>Note:</b> a call to <code>fmt.Print(e)</code> inside the 1708 <code>String</code> method will send the program into an infinite loop. 1709 You can avoid this by converting <code>e</code> first: 1710 <code>fmt.Print(float64(e))</code>. Why? 1711 <p> 1712 Change your <code>Sqrt</code> function to return an 1713 <code>ErrNegativeSqrt</code> value when given a negative number. 1714<div> 1715package main 1716 1717import ( 1718 "fmt" 1719 "os" 1720) 1721 1722func Sqrt(f float64) (float64, os.Error) { 1723 return 0, nil 1724} 1725 1726func main() { 1727 fmt.Println(Sqrt(2)) 1728 fmt.Println(Sqrt(-2)) 1729} 1730</div> 1731</div> 1732 1733<div class="slide localMode"> 1734 <h2>Exercise: HTTP Handlers</h2> 1735 <p> 1736 Implement the following types and define ServeHTTP methods on them. 1737 Register them to handle specific paths in your web server. 1738<pre>type String string 1739 1740type Struct struct { 1741 Greeting string 1742 Punct string 1743 Who string 1744}</pre> 1745 <p> 1746 For example, you should be able to register handlers using: 1747<pre>http.Handle("/string", String("I'm a frayed knot.")) 1748http.Handle("/struct", &Struct{"Hello", ":", "Gophers!"})</pre> 1749<div> 1750package main 1751 1752import ( 1753 "http" 1754) 1755 1756func main() { 1757 // your http.Handle calls here 1758 http.ListenAndServe("localhost:4000", nil) 1759} 1760</div> 1761</div> 1762 1763<div class="slide"> 1764 <h2>Exercise: Images</h2> 1765 <p> 1766 Remember the picture generator you wrote earlier? 1767 Let's write another one, but this time it will return 1768 an implementation of <code>image.Image</code> instead of a slice of data. 1769 <p> 1770 Define your own <code>Image</code> type, implement 1771 <a target="_blank" href="http://golang.org/pkg/image/#Image" target="_blank">the necessary methods</a>, 1772 and call <code>pic.ShowImage</code>. 1773 <p> 1774 <code>Bounds</code> should return a <code>image.Rectangle</code>, like 1775 <code>image.Rect(0, 0, w, h)</code>. 1776 <p> 1777 <code>ColorModel</code> should return <code>image.RGBAColorModel</code>. 1778 <p> 1779 <code>At</code> should return a color; 1780 the value <code>v</code> in the last picture generator corresponds to 1781 <code>image.RGBAColor{v, v, 255, 255}</code> in this one. 1782 1783<div> 1784package main 1785 1786import ( 1787 "image" 1788 "<span class="appengineMode">tour</span><span class="localMode">go-tour.googlecode.com/hg</span>/pic" 1789) 1790 1791type Image struct{} 1792 1793func main() { 1794 m := Image{} 1795 pic.ShowImage(m) 1796} 1797</div> 1798</div> 1799 1800<div class="slide"> 1801 <h2>Exercise: Rot13 Reader</h2> 1802 <p> 1803 A common pattern is an 1804 <a target="_blank" href="http://golang.org/pkg/io/#Reader">io.Reader</a> that wraps 1805 another <code>io.Reader</code>, modifying the stream in some way. 1806 <p> 1807 For example, the 1808 <a target="_blank" href="http://golang.org/pkg/compress/gzip/#Decompressor.NewReader">gzip.NewReader</a> 1809 function takes an <code>io.Reader</code> (a stream of gzipped data) 1810 and returns a <code>*gzip.Decompressor</code> that also implements 1811 <code>io.Reader</code> (a stream of the decompressed data). 1812 <p> 1813 Implement a <code>rot13Reader</code> that implements 1814 <code>io.Reader</code> and reads from an <code>io.Reader</code>, 1815 modifying the stream by applying the 1816 <a target="_blank" href="http://en.wikipedia.org/wiki/ROT13">ROT13</a> 1817 substitution cipher to all alphabetical characters. 1818 <p> 1819 The <code>rot13Reader</code> type is provided for you. Make it an 1820 <code>io.Reader</code> by implementing its <code>Read</code> method. 1821<div> 1822package main 1823 1824import ( 1825 "io" 1826 "os" 1827 "strings" 1828) 1829 1830type rot13Reader struct { 1831 r io.Reader 1832} 1833 1834func main() { 1835 s := strings.NewReader( 1836 "Lbh penpxrq gur pbqr!") 1837 r := rot13Reader{s} 1838 io.Copy(os.Stdout, &r) 1839} 1840</div> 1841</div> 1842 1843<div class="toc">Concurrency</div> 1844 1845<div class="slide nocode"> 1846<h2>Concurrency</h2> 1847</div> 1848 1849<div class="slide"> 1850 <h2>Goroutines</h2> 1851 <p> 1852 A <i>goroutine</i> is a lightweight thread managed by the Go runtime. 1853 <pre>go f(x, y, z)</pre> 1854 <p> 1855 starts a new goroutine running 1856 <pre>f(x, y, z)</pre> 1857 <p> 1858 The evaluation 1859 of <code>f</code>, <code>x</code>, <code>y</code>, and <code>z</code> 1860 happens in the current goroutine and the execution of <code>f</code> 1861 happens in the new goroutine. 1862 <p> 1863 Goroutines run in the same address space, so access to shared memory 1864 must be synchronized. The <code><a href="http://golang.org/pkg/sync/" 1865 target="_blank">sync</a></code> package provides useful primitives, 1866 although you won't need them much in Go as there are other primitives. 1867 (See the next slide.) 1868<div> 1869package main 1870 1871import ( 1872 "fmt" 1873 "<span class="appengineMode">runtime</span><span class="localMode">time</span>" 1874) 1875 1876func say(s string) { 1877 for i := 0; i < 5; i++ { 1878 <span class="appengineMode">runtime.Gosched()</span><span class="localMode">time.Sleep(100e6)</span> 1879 fmt.Println(s) 1880 } 1881} 1882 1883func main() { 1884 go say("world") 1885 say("hello") 1886} 1887</div> 1888</div> 1889 1890<div class="slide"> 1891 <h2>Channels</h2> 1892 1893 <p> 1894 Channels are a typed conduit through which you can send and receive values with the channel operator, <code><-</code>. 1895<pre> 1896ch <- v // Send v to channel ch. 1897v := <-ch // Receive from ch, and 1898 // assign value to v. 1899</pre> 1900 <p> 1901 (The data flows in the direction of the "arrow".) 1902 1903 <p> 1904 Like maps and slices, channels must be created before use: 1905<pre> 1906ch := make(chan int) 1907</pre> 1908 1909 <p> 1910 By default, sends and receives block until the other side is ready. 1911 This allows goroutines to synchronize without explicit locks or 1912 condition variables. 1913<div> 1914package main 1915 1916import "fmt" 1917 1918func sum(a []int, c chan int) { 1919 sum := 0 1920 for _, v := range a { 1921 sum += v 1922 } 1923 c <- sum // send sum to c 1924} 1925 1926func main() { 1927 a := []int{7, 2, 8, -9, 4, 0} 1928 1929 c := make(chan int) 1930 go sum(a[:len(a)/2], c) 1931 go sum(a[len(a)/2:], c) 1932 x, y := <-c, <-c // receive from c 1933 1934 fmt.Println(x, y, x + y) 1935} 1936</div> 1937</div> 1938 1939 1940<div class="slide"> 1941 <h2>Buffered Channels</h2> 1942 1943 <p> 1944 Channels can be <i>buffered</i>. Provide the buffer length as the 1945 second argument to <code>make</code> to initialize a buffered channel: 1946<pre> 1947ch := make(chan int, 100) 1948</pre> 1949 1950 <p> 1951 Sends to a buffered channel block only when the buffer is full. 1952 Receives block when the buffer is empty. 1953 1954 <p> 1955 Modify the example to overfill the buffer and see what happens. 1956 1957<div> 1958package main 1959 1960import "fmt" 1961 1962func main() { 1963 c := make(chan int, 2) 1964 c <- 1 1965 c <- 2 1966 fmt.Println(<-c) 1967 fmt.Println(<-c) 1968} 1969</div> 1970</div> 1971 1972<div class="slide"> 1973 <h2>Range and Close</h2> 1974 <p> 1975 A sender can <code>close</code> a channel to indicate that no more 1976 values will be sent. Receivers can test whether a channel has been 1977 closed by assigning a second parameter to the receive expression: after 1978 <pre> 1979v, ok := <-ch</pre> 1980 <p> 1981 <code>ok</code> is <code>false</code> if there are no more values to 1982 receive and the channel is closed. 1983 <p> 1984 The loop <code>for i := range c</code> receives values from the 1985 channel repeatedly until it is closed. 1986 <p> 1987 <b>Note:</b> Only the sender should close a channel, never the 1988 receiver. Sending on a closed channel will cause a panic. 1989 <p> 1990 <b>Another note</b>: Channels aren't like files; you don't usually 1991 need to close them. Closing is only necessary when the receiver must be 1992 told there are no more values coming. 1993<div> 1994package main 1995 1996import ( 1997 "fmt" 1998) 1999 2000func fibonacci(n int, c chan int) { 2001 x, y := 1, 1 2002 for i := 0; i < n; i++ { 2003 c <- x 2004 x, y = y, x + y 2005 } 2006 close(c) 2007} 2008 2009func main() { 2010 c := make(chan int, 10) 2011 go fibonacci(cap(c), c) 2012 for i := range c { 2013 fmt.Println(i) 2014 } 2015} 2016</div> 2017</div> 2018 2019<div class="slide"> 2020 <h2>Select</h2> 2021 <p> 2022 The <code>select</code> statement lets a goroutine wait on multiple 2023 communication operations. 2024 <p> 2025 A <code>select</code> blocks until one of its cases can run, then it 2026 executes that case. It chooses one at random if multiple are ready. 2027<div> 2028package main 2029 2030import "fmt" 2031 2032func fibonacci(c, quit chan int) { 2033 x, y := 1, 1 2034 for { 2035 select { 2036 case c <- x: 2037 x, y = y, x + y 2038 case <-quit: 2039 fmt.Println("quit") 2040 return 2041 } 2042 } 2043} 2044 2045func main() { 2046 c := make(chan int) 2047 quit := make(chan int) 2048 go func() { 2049 for i := 0; i < 10; i++ { 2050 fmt.Println(<-c) 2051 } 2052 quit <- 0 2053 }() 2054 fibonacci(c, quit) 2055} 2056</div> 2057</div> 2058 2059<div class="slide"> 2060 <h2>Default Selection</h2> 2061 <p> 2062 The <code>default</code> case in a <code>select</code> is run if no 2063 other case is ready. 2064 <p> 2065 Use a <code>default</code> case to try a send or receive without 2066 blocking: 2067 <pre> 2068select { 2069case i := <-c: 2070 // use i 2071default: 2072 // receiving from c would block 2073}</pre> 2074 <p> 2075 <span class="appengineMode"> 2076 <b>Note:</b> This example won't run through the web-based tour user 2077 interface because the 2078 <a target="_blank" href="http://golang.org/doc/play/">sandbox 2079 environment</a> has no concept of time. You may want to 2080 <a target="_blank" href="http://golang.org/doc/install.html">install 2081 Go</a> to see this example in action. 2082 </span> 2083<div> 2084package main 2085 2086import ( 2087 "fmt" 2088 "time" 2089) 2090 2091func main() { 2092 tick := time.Tick(1e8) 2093 boom := time.After(5e8) 2094 for { 2095 select { 2096 case <-tick: 2097 fmt.Println("tick.") 2098 case <-boom: 2099 fmt.Println("BOOM!") 2100 return 2101 default: 2102 fmt.Println(" .") 2103 time.Sleep(5e7) 2104 } 2105 } 2106} 2107</div> 2108</div> 2109 2110<div class="slide nocode"> 2111 <h2>Exercise: Equivalent Binary Trees</h2> 2112 <p> 2113 There can be many different binary trees with the same sequence of 2114 values stored at the leaves. 2115 For example, here are two binary trees storing the sequence 2116 1, 1, 2, 3, 5, 8, 13. 2117 <img src="static/fig4.png"> 2118 <p> 2119 A function to check whether two binary trees store the same sequence is 2120 quite complex in most languages. We'll use Go's concurrency and 2121 channels to write a simple solution. 2122 <p> 2123 This example uses the <code>tree</code> package, which defines the type: 2124<pre> 2125type Tree struct { 2126 Left *Tree 2127 Value int 2128 Right *Tree 2129} 2130</pre> 2131</div> 2132 2133<div class="slide"> 2134 <h2>Exercise: Equivalent Binary Trees</h2> 2135 <p> 2136 <b>1.</b> Implement the <code>Walk</code> function. 2137 <p> 2138 <b>2.</b> Test the <code>Walk</code> function. 2139 <p> 2140 The function <code>tree.New(k)</code> constructs a randomly-structured 2141 binary tree holding the values <code>k</code>, <code>2k</code>, <code>3k</code>, ..., 2142 <code>10k</code>. 2143 <p> 2144 Create a new channel <code>ch</code> and kick off the walker: 2145<pre> 2146go Walk(tree.New(1), ch) 2147</pre> 2148 <p> 2149 Then read and print 10 values from the channel. 2150 It should be the numbers 1, 2, 3, ..., 10. 2151 <p> 2152 <b>3.</b> Implement the <code>Same</code> function using <code>Walk</code> 2153 to determine whether <code>t1</code> and <code>t2</code> store the same values. 2154 <p> 2155 <b>4.</b> Test the <code>Same</code> function. 2156 <p> 2157 <code>Same(tree.New(1), tree.New(1))</code> should return true, and 2158 <code>Same(tree.New(1), tree.New(2))</code> should return false. 2159 2160<div> 2161package main 2162 2163import "<span class="appengineMode">tour</span><span class="localMode">go-tour.googlecode.com/hg</span>/tree" 2164 2165// Walk walks the tree t sending all values 2166// from the tree to the channel ch. 2167func Walk(t *tree.Tree, ch chan int) 2168 2169// Same determines whether the trees 2170// t1 and t2 contain the same values. 2171func Same(t1, t2 *tree.Tree) bool 2172 2173func main() { 2174} 2175</div> 2176</div> 2177 2178<div class="slide"> 2179 <h2>Exercise: Web Crawler</h2> 2180 <p> 2181 In this exercise you'll use Go's concurrency features to 2182 parallelize a web crawler. 2183 <p> 2184 Modify the <code>Crawl</code> function to fetch URLs in parallel 2185 without fetching the same URL twice. 2186<div> 2187package main 2188 2189import ( 2190 "os" 2191 "fmt" 2192) 2193 2194type Fetcher interface { 2195 // Fetch returns the body of URL and 2196 // a slice of URLs found on that page. 2197 Fetch(url string) (body string, urls []string, err os.Error) 2198} 2199 2200// Crawl uses fetcher to recursively crawl 2201// pages starting with url, to a maximum of depth. 2202func Crawl(url string, depth int, fetcher Fetcher) { 2203 // TODO: Fetch URLs in parallel. 2204 // TODO: Don't fetch the same URL twice. 2205 // This implementation doesn't do either: 2206 if depth <= 0 { 2207 return 2208 } 2209 body, urls, err := fetcher.Fetch(url) 2210 if err != nil { 2211 fmt.Println(err) 2212 return 2213 } 2214 fmt.Printf("found: %s %q\n", url, body) 2215 for _, u := range urls { 2216 Crawl(u, depth-1, fetcher) 2217 } 2218 return 2219} 2220 2221func main() { 2222 Crawl("http://golang.org/", 4, fetcher) 2223} 2224 2225 2226// fakeFetcher is Fetcher that returns canned results. 2227type fakeFetcher map[string]*fakeResult 2228 2229type fakeResult struct { 2230 body string 2231 urls []string 2232} 2233 2234func (f *fakeFetcher) Fetch(url string) (string, []string, os.Error) { 2235 if res, ok := (*f)[url]; ok { 2236 return res.body, res.urls, nil 2237 } 2238 return "", nil, fmt.Errorf("not found: %s", url) 2239} 2240 2241// fetcher is a populated fakeFetcher. 2242var fetcher = &fakeFetcher{ 2243 "http://golang.org/": &fakeResult{ 2244 "The Go Programming Language", 2245 []string{ 2246 "http://golang.org/pkg/", 2247 "http://golang.org/cmd/", 2248 }, 2249 }, 2250 "http://golang.org/pkg/": &fakeResult{ 2251 "Packages", 2252 []string{ 2253 "http://golang.org/", 2254 "http://golang.org/cmd/", 2255 "http://golang.org/pkg/fmt/", 2256 "http://golang.org/pkg/os/", 2257 }, 2258 }, 2259 "http://golang.org/pkg/fmt/": &fakeResult{ 2260 "Package fmt", 2261 []string{ 2262 "http://golang.org/", 2263 "http://golang.org/pkg/", 2264 }, 2265 }, 2266 "http://golang.org/pkg/os/": &fakeResult{ 2267 "Package os", 2268 []string{ 2269 "http://golang.org/", 2270 "http://golang.org/pkg/", 2271 }, 2272 }, 2273} 2274</div> 2275</div> 2276 2277<div class="slide nocode"> 2278 <h2>Where to Go from here...</h2> 2279 <p class="appengineMode"> 2280 You can get started by 2281 <a href="http://golang.org/doc/install.html">installing Go</a> or 2282 downloading the 2283 <a href="http://code.google.com/appengine/downloads.html#Google_App_Engine_SDK_for_Go">Go App Engine SDK</a>. 2284 </p> 2285 <p> 2286 <span class="appengineMode">Once you have Go on your machine, the</span> 2287 <span class="localMode">The</span> 2288 <a target="_blank" href="http://golang.org/doc/docs.html">Go Documentation</a> 2289 is a great place to 2290 <span class="appengineMode">continue</span> 2291 <span class="localMode">start</span>. 2292 It contains references, tutorials, videos, and more. 2293 <p> 2294 If you need help with the standard library, 2295 see the <a target="_blank" href="http://golang.org/pkg/">package 2296 reference</a>. For help with the language itself, you might be 2297 surprised to find the 2298 <a target="_blank" href="http://golang.org/doc/go_spec.html">Language 2299 Spec</a> is quite readable. 2300 <p> 2301 If you're interested in writing web applications, 2302 see the 2303 <a target="_blank" href="http://golang.org/doc/codelab/wiki/">Wiki 2304 Codelab</a>. 2305 <p> 2306 If you want to further explore Go's concurrency model, see the 2307 <a target="_blank" href="http://golang.org/doc/codewalk/sharemem/">Share Memory by Communicating</a> 2308 codewalk. 2309 <p> 2310 The <a target="_blank" href="http://golang.org/doc/codewalk/functions/">First Class Functions in Go</a> 2311 codewalk gives an interesting perspective on Go's function types. 2312 <p> 2313 The <a target="_blank" href="http://blog.golang.org/">Go Blog</a> has a 2314 large archive of informative Go articles. 2315 <p> 2316 Visit <a target="_blank" href="http://golang.org">golang.org</a> for 2317 more. 2318</div> 2319 2320</div><!-- end slides --> 2321 2322</body> 2323</html>