diff options
Diffstat (limited to 'doc')
123 files changed, 31447 insertions, 0 deletions
diff --git a/doc/ExpressivenessOfGo.pdf b/doc/ExpressivenessOfGo.pdf Binary files differnew file mode 100644 index 000000000..f1931d081 --- /dev/null +++ b/doc/ExpressivenessOfGo.pdf diff --git a/doc/GoCourseDay1.pdf b/doc/GoCourseDay1.pdf Binary files differnew file mode 100644 index 000000000..5a7749c18 --- /dev/null +++ b/doc/GoCourseDay1.pdf diff --git a/doc/GoCourseDay2.pdf b/doc/GoCourseDay2.pdf Binary files differnew file mode 100644 index 000000000..0d82ba4d3 --- /dev/null +++ b/doc/GoCourseDay2.pdf diff --git a/doc/GoCourseDay3.pdf b/doc/GoCourseDay3.pdf Binary files differnew file mode 100644 index 000000000..5a5463ba2 --- /dev/null +++ b/doc/GoCourseDay3.pdf diff --git a/doc/Makefile b/doc/Makefile new file mode 100644 index 000000000..e4e3f83b3 --- /dev/null +++ b/doc/Makefile @@ -0,0 +1,11 @@ +# Copyright 2009 The Go Authors. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +include ../src/Make.inc + +TARG=tmpltohtml +GOFILES=\ + tmpltohtml.go\ + +include ../src/Make.cmd diff --git a/doc/all.css b/doc/all.css new file mode 100644 index 000000000..f8f8c653f --- /dev/null +++ b/doc/all.css @@ -0,0 +1,204 @@ +/* General Styles */ +body { + font-family: "Bitstream Vera Sans", Verdana, sans-serif; + font-size: 81.25%; + line-height: 1.23em; + padding: 0; + margin: 1.23em; + background: white; + color: black; +} +a { + color: #04a; + text-decoration: none; +} +a:visited { + color: #04a; +} +a:hover { + color: #a40; + text-decoration: underline; +} +a:active { + color: #c00; +} +code, pre { + font-size: 1.2em; +} +pre { + background: #F0F0F0; + padding: 0.5em 1em; +} + +/* Top bar */ +#container { + width: 100%; + margin: auto; +} +#topnav { + height: 55px; + background: url(/doc/logo.png) no-repeat top left; +} +a#logo-box { + display: block; + height: 55px; +} +h1#title { + display: none; +} +#nav-main { + float: right; + width: 500px; + margin-top: -5px; + text-align: center; +} +#nav-main ul { + padding-left: 0; + margin-left: 0; + margin-bottom: 0.5em; +} +#nav-main li a { + display: inline; + display: inline-block; + padding: .46em .62em .38em .62em; +} +#nav-main li a:link, +#nav-main li a:visited { + color: #000; +} +#nav-main li { + display: inline; + display: inline-block; + background: #e6e6e6 url(/doc/button_background.png) repeat-x; + border: solid 1px #999; + margin-left: -1px; + text-shadow: #fff 0 1px 0; + box-shadow: 0 1px 1px #ccc; + -moz-box-shadow: 0 1px 1px #ccc; + -webkit-box-shadow: 0 1px 1px #ccc; +} +#nav-main li:first-child { + -moz-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; +} +#nav-main li:last-child { + -moz-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; +} +#nav-main .quickref { + color: #444; +} +#nav-main .quickref .sep { + color: #999; +} +#search { + width: 120px; + margin-left: 0.5em; +} +#search.inactive { + text-align: center; + color: #444; +} + +/* Footer */ +#site-info { + position: relative; + text-align: center; +} +#site-info, #site-info a:link, #site-info a:visited { + color: #aaa; +} + +/* Content */ +#content { + clear: both; + padding: 0; + position: relative; + margin-top: 1.5em; + margin-bottom: 1.5em; + border-top: solid 1px #aaa; + border-bottom: solid 1px #aaa; +} +.left-column { + width: 49%; + float: left; +} +.right-column { + width: 49%; + float: right; +} +.end-columns { + clear: both; +} +#content h1 { + padding: 0; +} +#content h2 { + border-top: 2px solid #ddd; + padding: 8px 0; + margin: 1.5em 0 0; +} +#content .subtitle { + margin-top: 1em; + display: block; +} +.navtop a { + font-weight: normal; font-size: 7pt; + float: right; color: #999; +} + +/* Content and Code Highlighting */ +pre.ebnf, pre.grammar { + background: #FFFFE0; +} +span.ln { + font-size: 80%; + color: #777777; +} +span.comment { + color: #002090; +} +span.highlight { + background: #FF9900; + font-weight: bold; +} +span.highlight-comment { + background: #FF9900; + font-weight: bold; + color: #002090; +} +span.selection { + background: #FFFF00 +} +span.selection-comment { + color: #002090; + background: #FFFF00 +} +span.selection-highlight { + background: #FF9900; + font-weight: bold; +} +span.selection-highlight-comment { + background: #FF9900; + font-weight: bold; + color: #002090; +} +span.alert { + color: #D00000; +} +#nav table { + width: 100%; +} +.detail { + padding: 0.25em 1em; + background: #F4F4F4; +} +sup.new { + color: red; + font-size: 8px; + line-height: 0; +} diff --git a/doc/button_background.png b/doc/button_background.png Binary files differnew file mode 100644 index 000000000..86a3b3086 --- /dev/null +++ b/doc/button_background.png diff --git a/doc/code.html b/doc/code.html new file mode 100644 index 000000000..cdc60b071 --- /dev/null +++ b/doc/code.html @@ -0,0 +1,368 @@ +<!-- How to Write Go Code --> + +<h2 id="Introduction">Introduction</h2> + +<p> +This document explains how to write a new package +and how to test code. +It assumes you have installed Go using the +<a href="install.html">installation instructions</a>. +</p> + +<p> +Before embarking on a change to an existing +package or the creation of a new package, +be sure to send mail to the +<a href="http://groups.google.com/group/golang-nuts">mailing list</a> +to let people know what you are thinking of doing. +Doing so helps avoid duplication of effort and +enables discussions about design before any code +has been written. +</p> + +<h2 id="Community_resources">Community resources</h2> + +<p> +For real-time help, there may be users or developers on +<code>#go-nuts</code> on the <a href="http://freenode.net/">Freenode</a> IRC server. +</p> + +<p> +The official mailing list for discussion of the Go language is +<a href="http://groups.google.com/group/golang-nuts">Go Nuts</a>. +</p> + +<p> +Bugs can be reported using the <a href="http://code.google.com/p/go/issues/list">Go issue tracker</a>. +</p> + +<p> +For those who wish to keep up with development, +there is another mailing list, <a href="http://groups.google.com/group/golang-checkins">golang-checkins</a>, +that receives a message summarizing each checkin to the Go repository. +</p> + + +<h2 id="New_package">Creating a new package</h2> + +<p> +The source code for the package with import path +<code>x/y</code> is, by convention, kept in the +directory <code>$GOROOT/src/pkg/x/y</code>. +</p> + +<h3>Makefile</h3> + +<p> +It would be nice to have Go-specific tools that +inspect the source files to determine what to build and in +what order, but for now, Go uses GNU <code>make</code>. +Thus, the first file to create in a new package directory is +usually the <code>Makefile</code>. +The basic form used in the Go source tree +is illustrated by <a href="../src/pkg/container/vector/Makefile"><code>src/pkg/container/vector/Makefile</code></a>: +</p> + +<pre> +include ../../../Make.inc + +TARG=container/vector +GOFILES=\ + intvector.go\ + stringvector.go\ + vector.go\ + +include ../../../Make.pkg +</pre> + +<p> +Outside the Go source tree (for personal packages), the standard form is +</p> + +<pre> +include $(GOROOT)/src/Make.inc + +TARG=mypackage +GOFILES=\ + my1.go\ + my2.go\ + +include $(GOROOT)/src/Make.pkg +</pre> + +<p> +The first and last lines <code>include</code> standard definitions and rules. +Packages maintained in the standard Go tree use a relative path (instead of +<code>$(GOROOT)/src</code>) so that <code>make</code> will work correctly +even if <code>$(GOROOT)</code> contains spaces. +This makes it easy for programmers to try Go. +</p> + +<p> +If you have not set <code>$GOROOT</code> in your environment, +you must run <code>gomake</code> to use this form of makefile. +<code>Gomake</code> also takes care to invoke GNU Make +even on systems where it is installed as <code>gmake</code> +rather than <code>make</code>. +</p> + +<p> +<code>TARG</code> is the target install path for the package, +the string that clients will use to import it. +Inside the Go tree, this string should be the same as the directory +in which the <code>Makefile</code> appears, with the +<code>$GOROOT/src/pkg/</code> prefix removed. +Outside the Go tree, you can use any <code>TARG</code> you +want that doesn't conflict with the standard Go package names. +A common convention is to use an identifying top-level name +to group your packages: <code>myname/tree</code>, <code>myname/filter</code>, etc. +Note that even if you keep your package source outside the +Go tree, running <code>make install</code> installs your +package binaries in the standard location—<code>$GOROOT/pkg</code>—to +make it easy to find them. +</p> + +<p> +<code>GOFILES</code> is a list of source files to compile to +create the package. The trailing <code>\</code> characters +allow the list to be split onto multiple lines +for easy sorting. +</p> + +<p> +If you create a new package directory in the Go tree, add it to the list in +<code>$GOROOT/src/pkg/Makefile</code> so that it +is included in the standard build. Then run: +<pre> +cd $GOROOT/src/pkg +./deps.bash +</pre> +<p> +to update the dependency file <code>Make.deps</code>. +(This happens automatically each time you run <code>all.bash</code> +or <code>make.bash</code>.) +</p> + +<p> +If you change the imports of an existing package, +you do not need to edit <code>$GOROOT/src/pkg/Makefile</code> +but you will still need to run <code>deps.bash</code> as above. +</p> + + +<h3>Go source files</h3> + +<p> +The first statement in each of the source files listed in the <code>Makefile</code> +should be <code>package <i>name</i></code>, where <code><i>name</i></code> +is the package's default name for imports. +(All files in a package must use the same <code><i>name</i></code>.) +Go's convention is that the package name is the last element of the +import path: the package imported as <code>"crypto/rot13"</code> +should be named <code>rot13</code>. +There is no requirement that package names be unique +across all packages linked into a single binary, +only that the import paths (their full file names) be unique. +</p> + +<p> +Go compiles all the source files in a package at once, so one file +can refer to constants, variables, types, and functions in another +file without special arrangement or declarations. +</p> + +<p> +Writing clean, idiomatic Go code is beyond the scope of this document. +<a href="effective_go.html">Effective Go</a> is an introduction to +that topic. +</p> + +<h2 id="Building_programs">Building programs</h2> +<p>To build a Go program with gomake, create a Makefile alongside your program's +source files. It should be similar to the example above, but include +<code>Make.cmd</code> instead of <code>Make.pkg</code>: + +<pre> +include $(GOROOT)/src/Make.inc + +TARG=helloworld +GOFILES=\ + helloworld.go\ + +include $(GOROOT)/src/Make.cmd +</pre> + +<p>Running <code>gomake</code> will compile <code>helloworld.go</code> +and produce an executable named <code>helloworld</code> in the current +directory. +</p> + +<p> +Running <code>gomake install</code> will build <code>helloworld</code> if +necessary and copy it to the <code>$GOBIN</code> directory +(<code>$GOROOT/bin/</code> is the default). +</p> + +<h2 id="Testing">Testing</h2> + +<p> +Go has a lightweight test framework known as <code>gotest</code>. +You write a test by creating a file with a name ending in <code>_test.go</code> +that contains functions named <code>TestXXX</code> with signature <code>func (t *testing.T)</code>. +The test framework runs each such function; +if the function calls a failure function such as <code>t.Error</code> or <code>t.Fail</code>, the test is considered to have failed. +The <a href="/cmd/gotest/">gotest command documentation</a> +and the <a href="/pkg/testing/">testing package documentation</a> give more detail. +</p> + +<p> +The <code>*_test.go</code> files should not be listed in the <code>Makefile</code>. +</p> + +<p> +To run the test, run either <code>make test</code> or <code>gotest</code> +(they are equivalent). +To run only the tests in a single test file, for instance <code>one_test.go</code>, +run <code>gotest one_test.go</code>. +</p> + +<p> +If your change affects performance, add a <code>Benchmark</code> function +(see the <a href="/cmd/gotest/">gotest command documentation</a>) +and run it using <code>gotest -test.bench=.</code>. +</p> + +<p> +Once your new code is tested and working, +it's time to get it <a href="contribute.html">reviewed and submitted</a>. +</p> + +<h2 id="pkg_example">An example package with tests</h2> + +<p> +This example package, <code>numbers</code>, consists of the function +<code>Double</code>, which takes an <code>int</code> and returns that value +multiplied by 2. It consists of three files. +</p> + +<p> +First, the package implementation, <code>numbers.go</code>: +</p> + +<pre> +package numbers + +func Double(i int) int { + return i * 2 +} +</pre> + +<p> +Next, the tests, <code>numbers_test.go</code>: +</p> + +<pre> +package numbers + +import ( + "testing" +) + +type doubleTest struct { + in, out int +} + +var doubleTests = []doubleTest{ + doubleTest{1, 2}, + doubleTest{2, 4}, + doubleTest{-5, -10}, +} + +func TestDouble(t *testing.T) { + for _, dt := range doubleTests { + v := Double(dt.in) + if v != dt.out { + t.Errorf("Double(%d) = %d, want %d.", dt.in, v, dt.out) + } + } +} +</pre> + +<p> +Finally, the <code>Makefile</code>: +</p> + +<pre> +include $(GOROOT)/src/Make.inc + +TARG=numbers +GOFILES=\ + numbers.go\ + +include $(GOROOT)/src/Make.pkg +</pre> + +<p> +Running <code>gomake install</code> will build and install the package to +the <code>$GOROOT/pkg/</code> directory (it can then be used by any +program on the system). +</p> + +<p> +Running <code>gomake test</code> (or just running the command +<code>gotest</code>) will rebuild the package, including the +<code>numbers_test.go</code> file, and then run the <code>TestDouble</code> +function. The output "<code>PASS</code>" indicates that all tests passed +successfully. Breaking the implementation by changing the multiplier from +<code>2</code> to <code>3</code> will allow you to see how failing tests are +reported. +</p> + +<p> +See the <a href="/cmd/gotest/">gotest documentation</a> and the +<a href="/pkg/testing/">testing package</a> for more detail. +</p> + +<h2 id="arch_os_specific">Architecture- and operating system-specific code</h2> + +<p>First, a disclaimer: very few Go packages should need to know about the +hardware and operating system they run on. In the vast majority of cases the +language and standard library handle most portability issues. This section is +a guide for experienced systems programmers who have a good reason to write +platform-specific code, such as assembly-language support for fast +trigonometric functions or code that implements a common interface above +different operating systems.</p> + +<p>To compile such code, use the <code>$GOOS</code> and <code>$GOARCH</code> +<a href="/doc/install.html#environment">environment variables</a> in your +source file names and <code>Makefile</code>.</p> + +<p>For example, this <code>Makefile</code> describes a package that builds on +different operating systems by parameterizing the file name with +<code>$GOOS</code>.</p> + +<pre> +include $(GOROOT)/src/Make.inc + +TARG=mypackage +GOFILES=\ + my.go\ + my_$(GOOS).go\ + +include $(GOROOT)/src/Make.pkg +</pre> + +<p>The OS-specific code goes in <code>my_linux.go</code>, +<code>my_darwin.go</code>, and so on.</p> + +<p>If you follow these conventional parameterizations, tools such as +<a href="/cmd/goinstall/">goinstall</a> will work seamlessly with your package: +</p> + +<pre> +my_$(GOOS).go +my_$(GOARCH).go +my_$(GOOS)_$(GOARCH).go +</pre> + +<p>The same holds for <code>.s</code> (assembly) files.</p> diff --git a/doc/codelab/wiki/Makefile b/doc/codelab/wiki/Makefile new file mode 100644 index 000000000..09c3291a0 --- /dev/null +++ b/doc/codelab/wiki/Makefile @@ -0,0 +1,25 @@ +# Copyright 2010 The Go Authors. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +include ../../../src/Make.inc + +all: index.html + +include ../../../src/Make.common + +CLEANFILES+=index.html srcextract.bin htmlify.bin get.bin + +index.html: srcextract.bin htmlify.bin + PATH=.:$$PATH awk '/^!/{system(substr($$0,2)); next} {print}' < wiki.html | tr -d '\r' > index.html + +test: get.bin + bash ./test.sh + rm -f get.6 get.bin + +%.bin: %.$O + $(LD) -o $@ $< + +%.$O: %.go + $(GC) $*.go + diff --git a/doc/codelab/wiki/edit.html b/doc/codelab/wiki/edit.html new file mode 100644 index 000000000..c14953b17 --- /dev/null +++ b/doc/codelab/wiki/edit.html @@ -0,0 +1,6 @@ +<h1>Editing {{.Title |html}}</h1> + +<form action="/save/{{.Title |html}}" method="POST"> +<div><textarea name="body" rows="20" cols="80">{{printf "%s" .Body |html}}</textarea></div> +<div><input type="submit" value="Save"></div> +</form> diff --git a/doc/codelab/wiki/final-noclosure.go b/doc/codelab/wiki/final-noclosure.go new file mode 100644 index 000000000..067f502c6 --- /dev/null +++ b/doc/codelab/wiki/final-noclosure.go @@ -0,0 +1,100 @@ +package main + +import ( + "http" + "io/ioutil" + "os" + "regexp" + "template" +) + +type Page struct { + Title string + Body []byte +} + +func (p *Page) save() os.Error { + filename := p.Title + ".txt" + return ioutil.WriteFile(filename, p.Body, 0600) +} + +func loadPage(title string) (*Page, os.Error) { + filename := title + ".txt" + body, err := ioutil.ReadFile(filename) + if err != nil { + return nil, err + } + return &Page{Title: title, Body: body}, nil +} + +func viewHandler(w http.ResponseWriter, r *http.Request) { + title, err := getTitle(w, r) + if err != nil { + return + } + p, err := loadPage(title) + if err != nil { + http.Redirect(w, r, "/edit/"+title, http.StatusFound) + return + } + renderTemplate(w, "view", p) +} + +func editHandler(w http.ResponseWriter, r *http.Request) { + title, err := getTitle(w, r) + if err != nil { + return + } + p, err := loadPage(title) + if err != nil { + p = &Page{Title: title} + } + renderTemplate(w, "edit", p) +} + +func saveHandler(w http.ResponseWriter, r *http.Request) { + title, err := getTitle(w, r) + if err != nil { + return + } + body := r.FormValue("body") + p := &Page{Title: title, Body: []byte(body)} + err = p.save() + if err != nil { + http.Error(w, err.String(), http.StatusInternalServerError) + return + } + http.Redirect(w, r, "/view/"+title, http.StatusFound) +} + +func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) { + t, err := template.ParseFile(tmpl+".html") + if err != nil { + http.Error(w, err.String(), http.StatusInternalServerError) + return + } + err = t.Execute(w, p) + if err != nil { + http.Error(w, err.String(), http.StatusInternalServerError) + } +} + +const lenPath = len("/view/") + +var titleValidator = regexp.MustCompile("^[a-zA-Z0-9]+$") + +func getTitle(w http.ResponseWriter, r *http.Request) (title string, err os.Error) { + title = r.URL.Path[lenPath:] + if !titleValidator.MatchString(title) { + http.NotFound(w, r) + err = os.NewError("Invalid Page Title") + } + return +} + +func main() { + http.HandleFunc("/view/", viewHandler) + http.HandleFunc("/edit/", editHandler) + http.HandleFunc("/save/", saveHandler) + http.ListenAndServe(":8080", nil) +} diff --git a/doc/codelab/wiki/final-noerror.go b/doc/codelab/wiki/final-noerror.go new file mode 100644 index 000000000..b8edbee9b --- /dev/null +++ b/doc/codelab/wiki/final-noerror.go @@ -0,0 +1,52 @@ +package main + +import ( + "http" + "io/ioutil" + "os" + "template" +) + +type Page struct { + Title string + Body []byte +} + +func (p *Page) save() os.Error { + filename := p.Title + ".txt" + return ioutil.WriteFile(filename, p.Body, 0600) +} + +func loadPage(title string) (*Page, os.Error) { + filename := title + ".txt" + body, err := ioutil.ReadFile(filename) + if err != nil { + return nil, err + } + return &Page{Title: title, Body: body}, nil +} + +const lenPath = len("/view/") + +func editHandler(w http.ResponseWriter, r *http.Request) { + title := r.URL.Path[lenPath:] + p, err := loadPage(title) + if err != nil { + p = &Page{Title: title} + } + t, _ := template.ParseFile("edit.html") + t.Execute(w, p) +} + +func viewHandler(w http.ResponseWriter, r *http.Request) { + title := r.URL.Path[lenPath:] + p, _ := loadPage(title) + t, _ := template.ParseFile("view.html") + t.Execute(w, p) +} + +func main() { + http.HandleFunc("/view/", viewHandler) + http.HandleFunc("/edit/", editHandler) + http.ListenAndServe(":8080", nil) +} diff --git a/doc/codelab/wiki/final-parsetemplate.go b/doc/codelab/wiki/final-parsetemplate.go new file mode 100644 index 000000000..f25012eed --- /dev/null +++ b/doc/codelab/wiki/final-parsetemplate.go @@ -0,0 +1,90 @@ +package main + +import ( + "http" + "io/ioutil" + "os" + "regexp" + "template" +) + +type Page struct { + Title string + Body []byte +} + +func (p *Page) save() os.Error { + filename := p.Title + ".txt" + return ioutil.WriteFile(filename, p.Body, 0600) +} + +func loadPage(title string) (*Page, os.Error) { + filename := title + ".txt" + body, err := ioutil.ReadFile(filename) + if err != nil { + return nil, err + } + return &Page{Title: title, Body: body}, nil +} + +func viewHandler(w http.ResponseWriter, r *http.Request, title string) { + p, err := loadPage(title) + if err != nil { + http.Redirect(w, r, "/edit/"+title, http.StatusFound) + return + } + renderTemplate(w, "view", p) +} + +func editHandler(w http.ResponseWriter, r *http.Request, title string) { + p, err := loadPage(title) + if err != nil { + p = &Page{Title: title} + } + renderTemplate(w, "edit", p) +} + +func saveHandler(w http.ResponseWriter, r *http.Request, title string) { + body := r.FormValue("body") + p := &Page{Title: title, Body: []byte(body)} + err := p.save() + if err != nil { + http.Error(w, err.String(), http.StatusInternalServerError) + return + } + http.Redirect(w, r, "/view/"+title, http.StatusFound) +} + +func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) { + t, err := template.ParseFile(tmpl+".html", nil) + if err != nil { + http.Error(w, err.String(), http.StatusInternalServerError) + return + } + err = t.Execute(w, p) + if err != nil { + http.Error(w, err.String(), http.StatusInternalServerError) + } +} + +const lenPath = len("/view/") + +var titleValidator = regexp.MustCompile("^[a-zA-Z0-9]+$") + +func makeHandler(fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + title := r.URL.Path[lenPath:] + if !titleValidator.MatchString(title) { + http.NotFound(w, r) + return + } + fn(w, r, title) + } +} + +func main() { + http.HandleFunc("/view/", makeHandler(viewHandler)) + http.HandleFunc("/edit/", makeHandler(editHandler)) + http.HandleFunc("/save/", makeHandler(saveHandler)) + http.ListenAndServe(":8080", nil) +} diff --git a/doc/codelab/wiki/final-template.go b/doc/codelab/wiki/final-template.go new file mode 100644 index 000000000..aab536ee1 --- /dev/null +++ b/doc/codelab/wiki/final-template.go @@ -0,0 +1,64 @@ +package main + +import ( + "http" + "io/ioutil" + "os" + "template" +) + +type Page struct { + Title string + Body []byte +} + +func (p *Page) save() os.Error { + filename := p.Title + ".txt" + return ioutil.WriteFile(filename, p.Body, 0600) +} + +func loadPage(title string) (*Page, os.Error) { + filename := title + ".txt" + body, err := ioutil.ReadFile(filename) + if err != nil { + return nil, err + } + return &Page{Title: title, Body: body}, nil +} + +const lenPath = len("/view/") + +func editHandler(w http.ResponseWriter, r *http.Request) { + title := r.URL.Path[lenPath:] + p, err := loadPage(title) + if err != nil { + p = &Page{Title: title} + } + renderTemplate(w, "edit", p) +} + +func viewHandler(w http.ResponseWriter, r *http.Request) { + title := r.URL.Path[lenPath:] + p, _ := loadPage(title) + renderTemplate(w, "view", p) +} + +func saveHandler(w http.ResponseWriter, r *http.Request) { + title := r.URL.Path[lenPath:] + body := r.FormValue("body") + p := &Page{Title: title, Body: []byte(body)} + p.save() + http.Redirect(w, r, "/view/"+title, http.StatusFound) +} + +func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) { + t, _ := template.ParseFile(tmpl+".html", nil) + t.Execute(w, p) +} + +func main() { + http.HandleFunc("/view/", viewHandler) + http.HandleFunc("/edit/", editHandler) + http.HandleFunc("/save/", saveHandler) + http.ListenAndServe(":8080", nil) +} diff --git a/doc/codelab/wiki/final.go b/doc/codelab/wiki/final.go new file mode 100644 index 000000000..47a4c3473 --- /dev/null +++ b/doc/codelab/wiki/final.go @@ -0,0 +1,94 @@ +package main + +import ( + "http" + "io/ioutil" + "os" + "regexp" + "template" +) + +type Page struct { + Title string + Body []byte +} + +func (p *Page) save() os.Error { + filename := p.Title + ".txt" + return ioutil.WriteFile(filename, p.Body, 0600) +} + +func loadPage(title string) (*Page, os.Error) { + filename := title + ".txt" + body, err := ioutil.ReadFile(filename) + if err != nil { + return nil, err + } + return &Page{Title: title, Body: body}, nil +} + +func viewHandler(w http.ResponseWriter, r *http.Request, title string) { + p, err := loadPage(title) + if err != nil { + http.Redirect(w, r, "/edit/"+title, http.StatusFound) + return + } + renderTemplate(w, "view", p) +} + +func editHandler(w http.ResponseWriter, r *http.Request, title string) { + p, err := loadPage(title) + if err != nil { + p = &Page{Title: title} + } + renderTemplate(w, "edit", p) +} + +func saveHandler(w http.ResponseWriter, r *http.Request, title string) { + body := r.FormValue("body") + p := &Page{Title: title, Body: []byte(body)} + err := p.save() + if err != nil { + http.Error(w, err.String(), http.StatusInternalServerError) + return + } + http.Redirect(w, r, "/view/"+title, http.StatusFound) +} + +var templates = make(map[string]*template.Template) + +func init() { + for _, tmpl := range []string{"edit", "view"} { + t := template.Must(template.ParseFile(tmpl+".html")) + templates[tmpl] = t + } +} + +func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) { + err := templates[tmpl].Execute(w, p) + if err != nil { + http.Error(w, err.String(), http.StatusInternalServerError) + } +} + +const lenPath = len("/view/") + +var titleValidator = regexp.MustCompile("^[a-zA-Z0-9]+$") + +func makeHandler(fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + title := r.URL.Path[lenPath:] + if !titleValidator.MatchString(title) { + http.NotFound(w, r) + return + } + fn(w, r, title) + } +} + +func main() { + http.HandleFunc("/view/", makeHandler(viewHandler)) + http.HandleFunc("/edit/", makeHandler(editHandler)) + http.HandleFunc("/save/", makeHandler(saveHandler)) + http.ListenAndServe(":8080", nil) +} diff --git a/doc/codelab/wiki/get.go b/doc/codelab/wiki/get.go new file mode 100644 index 000000000..c36684e3e --- /dev/null +++ b/doc/codelab/wiki/get.go @@ -0,0 +1,50 @@ +package main + +import ( + "http" + "flag" + "fmt" + "io" + "log" + "net" + "os" + "strings" +) + +var ( + post = flag.String("post", "", "urlencoded form data to POST") + addr = flag.Bool("addr", false, "find open address and print to stdout") +) + +func main() { + flag.Parse() + if *addr { + l, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + log.Fatal(err) + } + defer l.Close() + fmt.Print(l.Addr()) + return + } + url := flag.Arg(0) + if url == "" { + log.Fatal("no url supplied") + } + var r *http.Response + var err os.Error + if *post != "" { + b := strings.NewReader(*post) + r, err = http.Post(url, "application/x-www-form-urlencoded", b) + } else { + r, err = http.Get(url) + } + if err != nil { + log.Fatal(err) + } + defer r.Body.Close() + _, err = io.Copy(os.Stdout, r.Body) + if err != nil { + log.Fatal(err) + } +} diff --git a/doc/codelab/wiki/htmlify.go b/doc/codelab/wiki/htmlify.go new file mode 100644 index 000000000..9e7605b92 --- /dev/null +++ b/doc/codelab/wiki/htmlify.go @@ -0,0 +1,12 @@ +package main + +import ( + "template" + "os" + "io/ioutil" +) + +func main() { + b, _ := ioutil.ReadAll(os.Stdin) + template.HTMLEscape(os.Stdout, b) +} diff --git a/doc/codelab/wiki/http-sample.go b/doc/codelab/wiki/http-sample.go new file mode 100644 index 000000000..33379a1b6 --- /dev/null +++ b/doc/codelab/wiki/http-sample.go @@ -0,0 +1,15 @@ +package main + +import ( + "fmt" + "http" +) + +func handler(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:]) +} + +func main() { + http.HandleFunc("/", handler) + http.ListenAndServe(":8080", nil) +} diff --git a/doc/codelab/wiki/index.html b/doc/codelab/wiki/index.html new file mode 100644 index 000000000..50e9db5e9 --- /dev/null +++ b/doc/codelab/wiki/index.html @@ -0,0 +1,1007 @@ +<!-- Codelab: Writing Web Applications --> +<h2>Introduction</h2> + +<p> +Covered in this codelab: +</p> +<ul> +<li>Creating a data structure with load and save methods</li> +<li>Using the <code>http</code> package to build web applications +<li>Using the <code>template</code> package to process HTML templates</li> +<li>Using the <code>regexp</code> package to validate user input</li> +<li>Using closures</li> +</ul> + +<p> +Assumed knowledge: +</p> +<ul> +<li>Programming experience</li> +<li>Understanding of basic web technologies (HTTP, HTML)</li> +<li>Some UNIX command-line knowledge</li> +</ul> + +<h2>Getting Started</h2> + +<p> +At present, you need to have a Linux, OS X, or FreeBSD machine to run Go. If +you don't have access to one, you could set up a Linux Virtual Machine (using +<a href="http://www.virtualbox.org/">VirtualBox</a> or similar) or a +<a href="http://www.google.com/search?q=virtual+private+server">Virtual +Private Server</a>. +</p> + +<p> +Install Go (see the <a href="http://golang.org/doc/install.html">Installation Instructions</a>). +</p> + +<p> +Make a new directory for this codelab and cd to it: +</p> + +<pre> +$ mkdir ~/gowiki +$ cd ~/gowiki +</pre> + +<p> +Create a file named <code>wiki.go</code>, open it in your favorite editor, and +add the following lines: +</p> + +<pre> +package main + +import ( + "fmt" + "io/ioutil" + "os" +) +</pre> + +<p> +We import the <code>fmt</code>, <code>ioutil</code> and <code>os</code> +packages from the Go standard library. Later, as we implement additional +functionality, we will add more packages to this <code>import</code> +declaration. +</p> + +<h2>Data Structures</h2> + +<p> +Let's start by defining the data structures. A wiki consists of a series of +interconnected pages, each of which has a title and a body (the page content). +Here, we define <code>Page</code> as a struct with two fields representing +the title and body. +</p> + +<pre> +type Page struct { + Title string + Body []byte +} +</pre> + +<p> +The type <code>[]byte</code> means "a <code>byte</code> slice". +(See <a href="http://golang.org/doc/effective_go.html#slices">Effective Go</a> +for more on slices.) +The <code>Body</code> element is a <code>[]byte</code> rather than +<code>string</code> because that is the type expected by the <code>io</code> +libraries we will use, as you'll see below. +</p> + +<p> +The <code>Page</code> struct describes how page data will be stored in memory. +But what about persistent storage? We can address that by creating a +<code>save</code> method on <code>Page</code>: +</p> + +<pre> +func (p *Page) save() os.Error { + filename := p.Title + ".txt" + return ioutil.WriteFile(filename, p.Body, 0600) +} +</pre> + +<p> +This method's signature reads: "This is a method named <code>save</code> that +takes as its receiver <code>p</code>, a pointer to <code>Page</code> . It takes +no parameters, and returns a value of type <code>os.Error</code>." +</p> + +<p> +This method will save the <code>Page</code>'s <code>Body</code> to a text +file. For simplicity, we will use the <code>Title</code> as the file name. +</p> + +<p> +The <code>save</code> method returns an <code>os.Error</code> value because +that is the return type of <code>WriteFile</code> (a standard library function +that writes a byte slice to a file). The <code>save</code> method returns the +error value, to let the application handle it should anything go wrong while +writing the file. If all goes well, <code>Page.save()</code> will return +<code>nil</code> (the zero-value for pointers, interfaces, and some other +types). +</p> + +<p> +The octal integer constant <code>0600</code>, passed as the third parameter to +<code>WriteFile</code>, indicates that the file should be created with +read-write permissions for the current user only. (See the Unix man page +<code>open(2)</code> for details.) +</p> + +<p> +We will want to load pages, too: +</p> + +<pre> +func loadPage(title string) *Page { + filename := title + ".txt" + body, _ := ioutil.ReadFile(filename) + return &Page{Title: title, Body: body} +} +</pre> + +<p> +The function <code>loadPage</code> constructs the file name from +<code>Title</code>, reads the file's contents into a new +<code>Page</code>, and returns a pointer to that new <code>page</code>. +</p> + +<p> +Functions can return multiple values. The standard library function +<code>io.ReadFile</code> returns <code>[]byte</code> and <code>os.Error</code>. +In <code>loadPage</code>, error isn't being handled yet; the "blank identifier" +represented by the underscore (<code>_</code>) symbol is used to throw away the +error return value (in essence, assigning the value to nothing). +</p> + +<p> +But what happens if <code>ReadFile</code> encounters an error? For example, +the file might not exist. We should not ignore such errors. Let's modify the +function to return <code>*Page</code> and <code>os.Error</code>. +</p> + +<pre> +func loadPage(title string) (*Page, os.Error) { + filename := title + ".txt" + body, err := ioutil.ReadFile(filename) + if err != nil { + return nil, err + } + return &Page{Title: title, Body: body}, nil +} +</pre> + +<p> +Callers of this function can now check the second parameter; if it is +<code>nil</code> then it has successfully loaded a Page. If not, it will be an +<code>os.Error</code> that can be handled by the caller (see the <a +href="http://golang.org/pkg/os/#Error">os package documentation</a> for +details). +</p> + +<p> +At this point we have a simple data structure and the ability to save to and +load from a file. Let's write a <code>main</code> function to test what we've +written: +</p> + +<pre> +func main() { + p1 := &Page{Title: "TestPage", Body: []byte("This is a sample Page.")} + p1.save() + p2, _ := loadPage("TestPage") + fmt.Println(string(p2.Body)) +} +</pre> + +<p> +After compiling and executing this code, a file named <code>TestPage.txt</code> +would be created, containing the contents of <code>p1</code>. The file would +then be read into the struct <code>p2</code>, and its <code>Body</code> element +printed to the screen. +</p> + +<p> +You can compile and run the program like this: +</p> + +<pre> +$ 8g wiki.go +$ 8l wiki.8 +$ ./8.out +This is a sample page. +</pre> + +<p> +(The <code>8g</code> and <code>8l</code> commands are applicable to +<code>GOARCH=386</code>. If you're on an <code>amd64</code> system, +substitute 6's for the 8's.) +</p> + +<p> +<a href="part1.go">Click here to view the code we've written so far.</a> +</p> + +<h2>Introducing the <code>http</code> package (an interlude)</h2> + +<p> +Here's a full working example of a simple web server: +</p> + +<pre> +package main + +import ( + "fmt" + "http" +) + +func handler(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:]) +} + +func main() { + http.HandleFunc("/", handler) + http.ListenAndServe(":8080", nil) +} +</pre> + +<p> +The <code>main</code> function begins with a call to +<code>http.HandleFunc</code>, which tells the <code>http</code> package to +handle all requests to the web root (<code>"/"</code>) with +<code>handler</code>. +</p> + +<p> +It then calls <code>http.ListenAndServe</code>, specifying that it should +listen on port 8080 on any interface (<code>":8080"</code>). (Don't +worry about its second parameter, <code>nil</code>, for now.) +This function will block until the program is terminated. +</p> + +<p> +The function <code>handler</code> is of the type <code>http.HandlerFunc</code>. +It takes an <code>http.ResponseWriter</code> and an <code>http.Request</code> as +its arguments. +</p> + +<p> +An <code>http.ResponseWriter</code> value assembles the HTTP server's response; by writing +to it, we send data to the HTTP client. +</p> + +<p> +An <code>http.Request</code> is a data structure that represents the client +HTTP request. The string <code>r.URL.Path</code> is the path component +of the request URL. The trailing <code>[1:]</code> means +"create a sub-slice of <code>Path</code> from the 1st character to the end." +This drops the leading "/" from the path name. +</p> + +<p> +If you run this program and access the URL: +</p> +<pre>http://localhost:8080/monkeys</pre> +<p> +the program would present a page containing: +</p> +<pre>Hi there, I love monkeys!</pre> + +<h2>Using <code>http</code> to serve wiki pages</h2> + +<p> +To use the <code>http</code> package, it must be imported: +</p> + +<pre> +import ( + "fmt" + <b>"http"</b> + "io/ioutil" + "os" +) +</pre> + +<p> +Let's create a handler to view a wiki page: +</p> + +<pre> +const lenPath = len("/view/") + +func viewHandler(w http.ResponseWriter, r *http.Request) { + title := r.URL.Path[lenPath:] + p, _ := loadPage(title) + fmt.Fprintf(w, "<h1>%s</h1><div>%s</div>", p.Title, p.Body) +} +</pre> + +<p> +First, this function extracts the page title from <code>r.URL.Path</code>, +the path component of the request URL. The global constant +<code>lenPath</code> is the length of the leading <code>"/view/"</code> +component of the request path. +The <code>Path</code> is re-sliced with <code>[lenPath:]</code> to drop the +first 6 characters of the string. This is because the path will invariably +begin with <code>"/view/"</code>, which is not part of the page title. +</p> + +<p> +The function then loads the page data, formats the page with a string of simple +HTML, and writes it to <code>w</code>, the <code>http.ResponseWriter</code>. +</p> + +<p> +Again, note the use of <code>_</code> to ignore the <code>os.Error</code> +return value from <code>loadPage</code>. This is done here for simplicity +and generally considered bad practice. We will attend to this later. +</p> + +<p> +To use this handler, we create a <code>main</code> function that +initializes <code>http</code> using the <code>viewHandler</code> to handle +any requests under the path <code>/view/</code>. +</p> + +<pre> +func main() { + http.HandleFunc("/view/", viewHandler) + http.ListenAndServe(":8080", nil) +} +</pre> + +<p> +<a href="part2.go">Click here to view the code we've written so far.</a> +</p> + +<p> +Let's create some page data (as <code>test.txt</code>), compile our code, and +try serving a wiki page: +</p> + +<pre> +$ echo "Hello world" > test.txt +$ 8g wiki.go +$ 8l wiki.8 +$ ./8.out +</pre> + +<p> +With this web server running, a visit to <code><a +href="http://localhost:8080/view/test">http://localhost:8080/view/test</a></code> +should show a page titled "test" containing the words "Hello world". +</p> + +<h2>Editing Pages</h2> + +<p> +A wiki is not a wiki without the ability to edit pages. Let's create two new +handlers: one named <code>editHandler</code> to display an 'edit page' form, +and the other named <code>saveHandler</code> to save the data entered via the +form. +</p> + +<p> +First, we add them to <code>main()</code>: +</p> + +<pre> +func main() { + http.HandleFunc("/view/", viewHandler) + http.HandleFunc("/edit/", editHandler) + http.HandleFunc("/save/", saveHandler) + http.ListenAndServe(":8080", nil) +} +</pre> + +<p> +The function <code>editHandler</code> loads the page +(or, if it doesn't exist, create an empty <code>Page</code> struct), +and displays an HTML form. +</p> + +<pre> +func editHandler(w http.ResponseWriter, r *http.Request) { + title := r.URL.Path[lenPath:] + p, err := loadPage(title) + if err != nil { + p = &Page{Title: title} + } + fmt.Fprintf(w, "<h1>Editing %s</h1>"+ + "<form action=\"/save/%s\" method=\"POST\">"+ + "<textarea name=\"body\">%s</textarea><br>"+ + "<input type=\"submit\" value=\"Save\">"+ + "</form>", + p.Title, p.Title, p.Body) +} +</pre> + +<p> +This function will work fine, but all that hard-coded HTML is ugly. +Of course, there is a better way. +</p> + +<h2>The <code>template</code> package</h2> + +<p> +The <code>template</code> package is part of the Go standard library. +(A new template package is coming; this code lab will be updated soon.) +We can +use <code>template</code> to keep the HTML in a separate file, allowing +us to change the layout of our edit page without modifying the underlying Go +code. +</p> + +<p> +First, we must add <code>template</code> to the list of imports: +</p> + +<pre> +import ( + "http" + "io/ioutil" + "os" + <b>"template"</b> +) +</pre> + +<p> +Let's create a template file containing the HTML form. +Open a new file named <code>edit.html</code>, and add the following lines: +</p> + +<pre> +<h1>Editing {{.Title |html}}</h1> + +<form action="/save/{{.Title |html}}" method="POST"> +<div><textarea name="body" rows="20" cols="80">{{printf "%s" .Body |html}}</textarea></div> +<div><input type="submit" value="Save"></div> +</form> +</pre> + +<p> +Modify <code>editHandler</code> to use the template, instead of the hard-coded +HTML: +</p> + +<pre> +func editHandler(w http.ResponseWriter, r *http.Request) { + title := r.URL.Path[lenPath:] + p, err := loadPage(title) + if err != nil { + p = &Page{Title: title} + } + t, _ := template.ParseFile("edit.html") + t.Execute(w, p) +} +</pre> + +<p> +The function <code>template.ParseFile</code> will read the contents of +<code>edit.html</code> and return a <code>*template.Template</code>. +</p> + +<p> +The method <code>t.Execute</code> executes the template, writing the +generated HTML to the <code>http.ResponseWriter</code>. +The <code>.Title</code> and <code>.Body</code> dotted identifiers refer to +<code>p.Title</code> and <code>p.Body</code>. +</p> + +<p> +Template directives are enclosed in double curly braces. +The <code>printf "%s" .Body</code> instruction is a function call +that outputs <code>.Body</code> as a string instead of a stream of bytes, +the same as a call to <code>fmt.Printf</code>. +The <code>|html</code> part of each directive pipes the value through the +<code>html</code> formatter before outputting it, which escapes HTML +characters (such as replacing <code>></code> with <code>&gt;</code>), +preventing user data from corrupting the form HTML. +</p> + +<p> +Now that we've removed the <code>fmt.Fprintf</code> statement, we can remove +<code>"fmt"</code> from the <code>import</code> list. +</p> + +<p> +While we're working with templates, let's create a template for our +<code>viewHandler</code> called <code>view.html</code>: +</p> + +<pre> +<h1>{{.Title |html}}</h1> + +<p>[<a href="/edit/{{.Title |html}}">edit</a>]</p> + +<div>{{printf "%s" .Body |html}}</div> +</pre> + +<p> +Modify <code>viewHandler</code> accordingly: +</p> + +<pre> +func viewHandler(w http.ResponseWriter, r *http.Request) { + title := r.URL.Path[lenPath:] + p, _ := loadPage(title) + t, _ := template.ParseFile("view.html") + t.Execute(w, p) +} +</pre> + +<p> +Notice that we've used almost exactly the same templating code in both +handlers. Let's remove this duplication by moving the templating code +to its own function: +</p> + +<pre> +func viewHandler(w http.ResponseWriter, r *http.Request) { + title := r.URL.Path[lenPath:] + p, _ := loadPage(title) + renderTemplate(w, "view", p) +} + +func editHandler(w http.ResponseWriter, r *http.Request) { + title := r.URL.Path[lenPath:] + p, err := loadPage(title) + if err != nil { + p = &Page{Title: title} + } + renderTemplate(w, "edit", p) +} + +func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) { + t, _ := template.ParseFile(tmpl+".html", nil) + t.Execute(w, p) +} +</pre> + +<p> +The handlers are now shorter and simpler. +</p> + +<h2>Handling non-existent pages</h2> + +<p> +What if you visit <code>/view/APageThatDoesntExist</code>? The program will +crash. This is because it ignores the error return value from +<code>loadPage</code>. Instead, if the requested Page doesn't exist, it should +redirect the client to the edit Page so the content may be created: +</p> + +<pre> +func viewHandler(w http.ResponseWriter, r *http.Request) { + title, err := getTitle(w, r) + if err != nil { + return + } + p, err := loadPage(title) + if err != nil { + http.Redirect(w, r, "/edit/"+title, http.StatusFound) + return + } + renderTemplate(w, "view", p) +} +</pre> + +<p> +The <code>http.Redirect</code> function adds an HTTP status code of +<code>http.StatusFound</code> (302) and a <code>Location</code> +header to the HTTP response. +</p> + +<h2>Saving Pages</h2> + +<p> +The function <code>saveHandler</code> will handle the form submission. +</p> + +<pre> +func saveHandler(w http.ResponseWriter, r *http.Request) { + title := r.URL.Path[lenPath:] + body := r.FormValue("body") + p := &Page{Title: title, Body: []byte(body)} + p.save() + http.Redirect(w, r, "/view/"+title, http.StatusFound) +} +</pre> + +<p> +The page title (provided in the URL) and the form's only field, +<code>Body</code>, are stored in a new <code>Page</code>. +The <code>save()</code> method is then called to write the data to a file, +and the client is redirected to the <code>/view/</code> page. +</p> + +<p> +The value returned by <code>FormValue</code> is of type <code>string</code>. +We must convert that value to <code>[]byte</code> before it will fit into +the <code>Page</code> struct. We use <code>[]byte(body)</code> to perform +the conversion. +</p> + +<h2>Error handling</h2> + +<p> +There are several places in our program where errors are being ignored. This +is bad practice, not least because when an error does occur the program will +crash. A better solution is to handle the errors and return an error message +to the user. That way if something does go wrong, the server will continue to +function and the user will be notified. +</p> + +<p> +First, let's handle the errors in <code>renderTemplate</code>: +</p> + +<pre> +func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) { + t, err := template.ParseFile(tmpl+".html", nil) + if err != nil { + http.Error(w, err.String(), http.StatusInternalServerError) + return + } + err = t.Execute(w, p) + if err != nil { + http.Error(w, err.String(), http.StatusInternalServerError) + } +} +</pre> + +<p> +The <code>http.Error</code> function sends a specified HTTP response code +(in this case "Internal Server Error") and error message. +Already the decision to put this in a separate function is paying off. +</p> + +<p> +Now let's fix up <code>saveHandler</code>: +</p> + +<pre> +func saveHandler(w http.ResponseWriter, r *http.Request) { + title, err := getTitle(w, r) + if err != nil { + return + } + body := r.FormValue("body") + p := &Page{Title: title, Body: []byte(body)} + err = p.save() + if err != nil { + http.Error(w, err.String(), http.StatusInternalServerError) + return + } + http.Redirect(w, r, "/view/"+title, http.StatusFound) +} +</pre> + +<p> +Any errors that occur during <code>p.save()</code> will be reported +to the user. +</p> + +<h2>Template caching</h2> + +<p> +There is an inefficiency in this code: <code>renderTemplate</code> calls +<code>ParseFile</code> every time a page is rendered. +A better approach would be to call <code>ParseFile</code> once for each +template at program initialization, and store the resultant +<code>*Template</code> values in a data structure for later use. +</p> + +<p> +First we create a global map named <code>templates</code> in which to store +our <code>*Template</code> values, keyed by <code>string</code> +(the template name): +</p> + +<pre> +var templates = make(map[string]*template.Template) +</pre> + +<p> +Then we create an <code>init</code> function, which will be called before +<code>main</code> at program initialization. The function +<code>template.Must</code> is a convenience wrapper that panics when passed a +non-nil <code>os.Error</code> value, and otherwise returns the +<code>*Template</code> unaltered. A panic is appropriate here; if the templates +can't be loaded the only sensible thing to do is exit the program. +</p> + +<pre> +func init() { + for _, tmpl := range []string{"edit", "view"} { + t := template.Must(template.ParseFile(tmpl + ".html")) + templates[tmpl] = t + } +} +</pre> + +<p> +A <code>for</code> loop is used with a <code>range</code> statement to iterate +over an array constant containing the names of the templates we want parsed. +If we were to add more templates to our program, we would add their names to +that array. +</p> + +<p> +We then modify our <code>renderTemplate</code> function to call +the <code>Execute</code> method on the appropriate <code>Template</code> from +<code>templates</code>: + +<pre> +func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) { + err := templates[tmpl].Execute(w, p) + if err != nil { + http.Error(w, err.String(), http.StatusInternalServerError) + } +} +</pre> + +<h2>Validation</h2> + +<p> +As you may have observed, this program has a serious security flaw: a user +can supply an arbitrary path to be read/written on the server. To mitigate +this, we can write a function to validate the title with a regular expression. +</p> + +<p> +First, add <code>"regexp"</code> to the <code>import</code> list. +Then we can create a global variable to store our validation regexp: +</p> + +<pre> +var titleValidator = regexp.MustCompile("^[a-zA-Z0-9]+$") +</pre> + +<p> +The function <code>regexp.MustCompile</code> will parse and compile the +regular expression, and return a <code>regexp.Regexp</code>. +<code>MustCompile</code> is distinct from <code>Compile</code> in that it will +panic if the expression compilation fails, while <code>Compile</code> returns +an <code>os.Error</code> as a second parameter. +</p> + +<p> +Now, let's write a function that extracts the title string from the request +URL, and tests it against our <code>TitleValidator</code> expression: +</p> + +<pre> +func getTitle(w http.ResponseWriter, r *http.Request) (title string, err os.Error) { + title = r.URL.Path[lenPath:] + if !titleValidator.MatchString(title) { + http.NotFound(w, r) + err = os.NewError("Invalid Page Title") + } + return +} +</pre> + +<p> +If the title is valid, it will be returned along with a <code>nil</code> +error value. If the title is invalid, the function will write a +"404 Not Found" error to the HTTP connection, and return an error to the +handler. +</p> + +<p> +Let's put a call to <code>getTitle</code> in each of the handlers: +</p> + +<pre> +func viewHandler(w http.ResponseWriter, r *http.Request) { + title, err := getTitle(w, r) + if err != nil { + return + } + p, err := loadPage(title) + if err != nil { + http.Redirect(w, r, "/edit/"+title, http.StatusFound) + return + } + renderTemplate(w, "view", p) +} + +func editHandler(w http.ResponseWriter, r *http.Request) { + title, err := getTitle(w, r) + if err != nil { + return + } + p, err := loadPage(title) + if err != nil { + p = &Page{Title: title} + } + renderTemplate(w, "edit", p) +} + +func saveHandler(w http.ResponseWriter, r *http.Request) { + title, err := getTitle(w, r) + if err != nil { + return + } + body := r.FormValue("body") + p := &Page{Title: title, Body: []byte(body)} + err = p.save() + if err != nil { + http.Error(w, err.String(), http.StatusInternalServerError) + return + } + http.Redirect(w, r, "/view/"+title, http.StatusFound) +} +</pre> + +<h2>Introducing Function Literals and Closures</h2> + +<p> +Catching the error condition in each handler introduces a lot of repeated code. +What if we could wrap each of the handlers in a function that does this +validation and error checking? Go's +<a href="http://golang.org/doc/go_spec.html#Function_declarations">function +literals</a> provide a powerful means of abstracting functionality +that can help us here. +</p> + +<p> +First, we re-write the function definition of each of the handlers to accept +a title string: +</p> + +<pre> +func viewHandler(w http.ResponseWriter, r *http.Request, title string) +func editHandler(w http.ResponseWriter, r *http.Request, title string) +func saveHandler(w http.ResponseWriter, r *http.Request, title string) +</pre> + +<p> +Now let's define a wrapper function that <i>takes a function of the above +type</i>, and returns a function of type <code>http.HandlerFunc</code> +(suitable to be passed to the function <code>http.HandleFunc</code>): +</p> + +<pre> +func makeHandler(fn func (http.ResponseWriter, *http.Request, string)) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + // Here we will extract the page title from the Request, + // and call the provided handler 'fn' + } +} +</pre> + +<p> +The returned function is called a closure because it encloses values defined +outside of it. In this case, the variable <code>fn</code> (the single argument +to <code>makeHandler</code>) is enclosed by the closure. The variable +<code>fn</code> will be one of our save, edit, or view handlers. +</p> + +<p> +Now we can take the code from <code>getTitle</code> and use it here +(with some minor modifications): +</p> + +<pre> +func makeHandler(fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + title := r.URL.Path[lenPath:] + if !titleValidator.MatchString(title) { + http.NotFound(w, r) + return + } + fn(w, r, title) + } +} +</pre> + +<p> +The closure returned by <code>makeHandler</code> is a function that takes +an <code>http.ResponseWriter</code> and <code>http.Request</code> (in other +words, an <code>http.HandlerFunc</code>). +The closure extracts the <code>title</code> from the request path, and +validates it with the <code>TitleValidator</code> regexp. If the +<code>title</code> is invalid, an error will be written to the +<code>ResponseWriter</code> using the <code>http.NotFound</code> function. +If the <code>title</code> is valid, the enclosed handler function +<code>fn</code> will be called with the <code>ResponseWriter</code>, +<code>Request</code>, and <code>title</code> as arguments. +</p> + +<p> +Now we can wrap the handler functions with <code>makeHandler</code> in +<code>main</code>, before they are registered with the <code>http</code> +package: +</p> + +<pre> +func main() { + http.HandleFunc("/view/", makeHandler(viewHandler)) + http.HandleFunc("/edit/", makeHandler(editHandler)) + http.HandleFunc("/save/", makeHandler(saveHandler)) + http.ListenAndServe(":8080", nil) +} +</pre> + +<p> +Finally we remove the calls to <code>getTitle</code> from the handler functions, +making them much simpler: +</p> + +<pre> +func viewHandler(w http.ResponseWriter, r *http.Request, title string) { + p, err := loadPage(title) + if err != nil { + http.Redirect(w, r, "/edit/"+title, http.StatusFound) + return + } + renderTemplate(w, "view", p) +} + +func editHandler(w http.ResponseWriter, r *http.Request, title string) { + p, err := loadPage(title) + if err != nil { + p = &Page{Title: title} + } + renderTemplate(w, "edit", p) +} + +func saveHandler(w http.ResponseWriter, r *http.Request, title string) { + body := r.FormValue("body") + p := &Page{Title: title, Body: []byte(body)} + err := p.save() + if err != nil { + http.Error(w, err.String(), http.StatusInternalServerError) + return + } + http.Redirect(w, r, "/view/"+title, http.StatusFound) +} +</pre> + +<h2>Try it out!</h2> + +<p> +<a href="final.go">Click here to view the final code listing.</a> +</p> + +<p> +Recompile the code, and run the app: +</p> + +<pre> +$ 8g wiki.go +$ 8l wiki.8 +$ ./8.out +</pre> + +<p> +Visiting <a href="http://localhost:8080/view/ANewPage">http://localhost:8080/view/ANewPage</a> +should present you with the page edit form. You should then be able to +enter some text, click 'Save', and be redirected to the newly created page. +</p> + +<h2>Other tasks</h2> + +<p> +Here are some simple tasks you might want to tackle on your own: +</p> + +<ul> +<li>Store templates in <code>tmpl/</code> and page data in <code>data/</code>. +<li>Add a handler to make the web root redirect to + <code>/view/FrontPage</code>.</li> +<li>Spruce up the page templates by making them valid HTML and adding some + CSS rules.</li> +<li>Implement inter-page linking by converting instances of + <code>[PageName]</code> to <br> + <code><a href="/view/PageName">PageName</a></code>. + (hint: you could use <code>regexp.ReplaceAllFunc</code> to do this) + </li> +</ul> diff --git a/doc/codelab/wiki/notemplate.go b/doc/codelab/wiki/notemplate.go new file mode 100644 index 000000000..9cbe9ad76 --- /dev/null +++ b/doc/codelab/wiki/notemplate.go @@ -0,0 +1,55 @@ +package main + +import ( + "fmt" + "http" + "io/ioutil" + "os" +) + +type Page struct { + Title string + Body []byte +} + +func (p *Page) save() os.Error { + filename := p.Title + ".txt" + return ioutil.WriteFile(filename, p.Body, 0600) +} + +func loadPage(title string) (*Page, os.Error) { + filename := title + ".txt" + body, err := ioutil.ReadFile(filename) + if err != nil { + return nil, err + } + return &Page{Title: title, Body: body}, nil +} + +const lenPath = len("/view/") + +func viewHandler(w http.ResponseWriter, r *http.Request) { + title := r.URL.Path[lenPath:] + p, _ := loadPage(title) + fmt.Fprintf(w, "<h1>%s</h1><div>%s</div>", p.Title, p.Body) +} + +func editHandler(w http.ResponseWriter, r *http.Request) { + title := r.URL.Path[lenPath:] + p, err := loadPage(title) + if err != nil { + p = &Page{Title: title} + } + fmt.Fprintf(w, "<h1>Editing %s</h1>"+ + "<form action=\"/save/%s\" method=\"POST\">"+ + "<textarea name=\"body\">%s</textarea><br>"+ + "<input type=\"submit\" value=\"Save\">"+ + "</form>", + p.Title, p.Title, p.Body) +} + +func main() { + http.HandleFunc("/view/", viewHandler) + http.HandleFunc("/edit/", editHandler) + http.ListenAndServe(":8080", nil) +} diff --git a/doc/codelab/wiki/part1-noerror.go b/doc/codelab/wiki/part1-noerror.go new file mode 100644 index 000000000..14cfc321a --- /dev/null +++ b/doc/codelab/wiki/part1-noerror.go @@ -0,0 +1,30 @@ +package main + +import ( + "fmt" + "io/ioutil" + "os" +) + +type Page struct { + Title string + Body []byte +} + +func (p *Page) save() os.Error { + filename := p.Title + ".txt" + return ioutil.WriteFile(filename, p.Body, 0600) +} + +func loadPage(title string) *Page { + filename := title + ".txt" + body, _ := ioutil.ReadFile(filename) + return &Page{Title: title, Body: body} +} + +func main() { + p1 := &Page{Title: "TestPage", Body: []byte("This is a sample page.")} + p1.save() + p2 := loadPage("TestPage") + fmt.Println(string(p2.Body)) +} diff --git a/doc/codelab/wiki/part1.go b/doc/codelab/wiki/part1.go new file mode 100644 index 000000000..4b0654f8b --- /dev/null +++ b/doc/codelab/wiki/part1.go @@ -0,0 +1,33 @@ +package main + +import ( + "fmt" + "io/ioutil" + "os" +) + +type Page struct { + Title string + Body []byte +} + +func (p *Page) save() os.Error { + filename := p.Title + ".txt" + return ioutil.WriteFile(filename, p.Body, 0600) +} + +func loadPage(title string) (*Page, os.Error) { + filename := title + ".txt" + body, err := ioutil.ReadFile(filename) + if err != nil { + return nil, err + } + return &Page{Title: title, Body: body}, nil +} + +func main() { + p1 := &Page{Title: "TestPage", Body: []byte("This is a sample Page.")} + p1.save() + p2, _ := loadPage("TestPage") + fmt.Println(string(p2.Body)) +} diff --git a/doc/codelab/wiki/part2.go b/doc/codelab/wiki/part2.go new file mode 100644 index 000000000..d57c3a01f --- /dev/null +++ b/doc/codelab/wiki/part2.go @@ -0,0 +1,40 @@ +package main + +import ( + "fmt" + "http" + "io/ioutil" + "os" +) + +type Page struct { + Title string + Body []byte +} + +func (p *Page) save() os.Error { + filename := p.Title + ".txt" + return ioutil.WriteFile(filename, p.Body, 0600) +} + +func loadPage(title string) (*Page, os.Error) { + filename := title + ".txt" + body, err := ioutil.ReadFile(filename) + if err != nil { + return nil, err + } + return &Page{Title: title, Body: body}, nil +} + +const lenPath = len("/view/") + +func viewHandler(w http.ResponseWriter, r *http.Request) { + title := r.URL.Path[lenPath:] + p, _ := loadPage(title) + fmt.Fprintf(w, "<h1>%s</h1><div>%s</div>", p.Title, p.Body) +} + +func main() { + http.HandleFunc("/view/", viewHandler) + http.ListenAndServe(":8080", nil) +} diff --git a/doc/codelab/wiki/srcextract.go b/doc/codelab/wiki/srcextract.go new file mode 100644 index 000000000..6b5fbcb43 --- /dev/null +++ b/doc/codelab/wiki/srcextract.go @@ -0,0 +1,72 @@ +package main + +import ( + "bytes" + "flag" + "go/parser" + "go/printer" + "go/ast" + "go/token" + "log" + "template" + "os" +) + +var ( + srcFn = flag.String("src", "", "source filename") + getName = flag.String("name", "", "func/type name to output") + html = flag.Bool("html", true, "output HTML") + showPkg = flag.Bool("pkg", false, "show package in output") +) + +func main() { + // handle input + flag.Parse() + if *srcFn == "" || *getName == "" { + flag.Usage() + os.Exit(2) + } + // load file + fs := token.NewFileSet() + file, err := parser.ParseFile(fs, *srcFn, nil, 0) + if err != nil { + log.Fatal(err) + } + // create filter + filter := func(name string) bool { + return name == *getName + } + // filter + if !ast.FilterFile(file, filter) { + os.Exit(1) + } + // print the AST + var b bytes.Buffer + printer.Fprint(&b, fs, file) + // drop package declaration + if !*showPkg { + for { + c, err := b.ReadByte() + if c == '\n' || err != nil { + break + } + } + } + // drop leading newlines + for { + b, err := b.ReadByte() + if err != nil { + break + } + if b != '\n' { + os.Stdout.Write([]byte{b}) + break + } + } + // output + if *html { + template.HTMLEscape(os.Stdout, b.Bytes()) + } else { + b.WriteTo(os.Stdout) + } +} diff --git a/doc/codelab/wiki/test.sh b/doc/codelab/wiki/test.sh new file mode 100755 index 000000000..ed63ff20f --- /dev/null +++ b/doc/codelab/wiki/test.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +set -e +wiki_pid= +cleanup() { + kill $wiki_pid + rm -f test_*.out Test.txt final-test.bin final-test.go +} +trap cleanup 0 INT + +gomake get.bin +addr=$(./get.bin -addr) +sed s/:8080/$addr/ < final.go > final-test.go +gomake final-test.bin +(./final-test.bin) & +wiki_pid=$! + +sleep 1 + +./get.bin http://$addr/edit/Test > test_edit.out +diff -u test_edit.out test_edit.good +./get.bin -post=body=some%20content http://$addr/save/Test +diff -u Test.txt test_Test.txt.good +./get.bin http://$addr/view/Test > test_view.out +diff -u test_view.out test_view.good + +echo PASS diff --git a/doc/codelab/wiki/test_Test.txt.good b/doc/codelab/wiki/test_Test.txt.good new file mode 100644 index 000000000..f0eec86f6 --- /dev/null +++ b/doc/codelab/wiki/test_Test.txt.good @@ -0,0 +1 @@ +some content
\ No newline at end of file diff --git a/doc/codelab/wiki/test_edit.good b/doc/codelab/wiki/test_edit.good new file mode 100644 index 000000000..36c6dbb73 --- /dev/null +++ b/doc/codelab/wiki/test_edit.good @@ -0,0 +1,6 @@ +<h1>Editing Test</h1> + +<form action="/save/Test" method="POST"> +<div><textarea name="body" rows="20" cols="80"></textarea></div> +<div><input type="submit" value="Save"></div> +</form> diff --git a/doc/codelab/wiki/test_view.good b/doc/codelab/wiki/test_view.good new file mode 100644 index 000000000..07e8edb22 --- /dev/null +++ b/doc/codelab/wiki/test_view.good @@ -0,0 +1,5 @@ +<h1>Test</h1> + +<p>[<a href="/edit/Test">edit</a>]</p> + +<div>some content</div> diff --git a/doc/codelab/wiki/view.html b/doc/codelab/wiki/view.html new file mode 100644 index 000000000..023391577 --- /dev/null +++ b/doc/codelab/wiki/view.html @@ -0,0 +1,5 @@ +<h1>{{.Title |html}}</h1> + +<p>[<a href="/edit/{{.Title |html}}">edit</a>]</p> + +<div>{{printf "%s" .Body |html}}</div> diff --git a/doc/codelab/wiki/wiki.html b/doc/codelab/wiki/wiki.html new file mode 100644 index 000000000..634babd8b --- /dev/null +++ b/doc/codelab/wiki/wiki.html @@ -0,0 +1,784 @@ +<!-- Codelab: Writing Web Applications --> +<h2>Introduction</h2> + +<p> +Covered in this codelab: +</p> +<ul> +<li>Creating a data structure with load and save methods</li> +<li>Using the <code>http</code> package to build web applications +<li>Using the <code>template</code> package to process HTML templates</li> +<li>Using the <code>regexp</code> package to validate user input</li> +<li>Using closures</li> +</ul> + +<p> +Assumed knowledge: +</p> +<ul> +<li>Programming experience</li> +<li>Understanding of basic web technologies (HTTP, HTML)</li> +<li>Some UNIX command-line knowledge</li> +</ul> + +<h2>Getting Started</h2> + +<p> +At present, you need to have a Linux, OS X, or FreeBSD machine to run Go. If +you don't have access to one, you could set up a Linux Virtual Machine (using +<a href="http://www.virtualbox.org/">VirtualBox</a> or similar) or a +<a href="http://www.google.com/search?q=virtual+private+server">Virtual +Private Server</a>. +</p> + +<p> +Install Go (see the <a href="http://golang.org/doc/install.html">Installation Instructions</a>). +</p> + +<p> +Make a new directory for this codelab and cd to it: +</p> + +<pre> +$ mkdir ~/gowiki +$ cd ~/gowiki +</pre> + +<p> +Create a file named <code>wiki.go</code>, open it in your favorite editor, and +add the following lines: +</p> + +<pre> +package main + +import ( + "fmt" + "io/ioutil" + "os" +) +</pre> + +<p> +We import the <code>fmt</code>, <code>ioutil</code> and <code>os</code> +packages from the Go standard library. Later, as we implement additional +functionality, we will add more packages to this <code>import</code> +declaration. +</p> + +<h2>Data Structures</h2> + +<p> +Let's start by defining the data structures. A wiki consists of a series of +interconnected pages, each of which has a title and a body (the page content). +Here, we define <code>Page</code> as a struct with two fields representing +the title and body. +</p> + +<pre> +!srcextract.bin -src=part1.go -name=Page +</pre> + +<p> +The type <code>[]byte</code> means "a <code>byte</code> slice". +(See <a href="http://golang.org/doc/effective_go.html#slices">Effective Go</a> +for more on slices.) +The <code>Body</code> element is a <code>[]byte</code> rather than +<code>string</code> because that is the type expected by the <code>io</code> +libraries we will use, as you'll see below. +</p> + +<p> +The <code>Page</code> struct describes how page data will be stored in memory. +But what about persistent storage? We can address that by creating a +<code>save</code> method on <code>Page</code>: +</p> + +<pre> +!srcextract.bin -src=part1.go -name=save +</pre> + +<p> +This method's signature reads: "This is a method named <code>save</code> that +takes as its receiver <code>p</code>, a pointer to <code>Page</code> . It takes +no parameters, and returns a value of type <code>os.Error</code>." +</p> + +<p> +This method will save the <code>Page</code>'s <code>Body</code> to a text +file. For simplicity, we will use the <code>Title</code> as the file name. +</p> + +<p> +The <code>save</code> method returns an <code>os.Error</code> value because +that is the return type of <code>WriteFile</code> (a standard library function +that writes a byte slice to a file). The <code>save</code> method returns the +error value, to let the application handle it should anything go wrong while +writing the file. If all goes well, <code>Page.save()</code> will return +<code>nil</code> (the zero-value for pointers, interfaces, and some other +types). +</p> + +<p> +The octal integer constant <code>0600</code>, passed as the third parameter to +<code>WriteFile</code>, indicates that the file should be created with +read-write permissions for the current user only. (See the Unix man page +<code>open(2)</code> for details.) +</p> + +<p> +We will want to load pages, too: +</p> + +<pre> +!srcextract.bin -src=part1-noerror.go -name=loadPage +</pre> + +<p> +The function <code>loadPage</code> constructs the file name from +<code>Title</code>, reads the file's contents into a new +<code>Page</code>, and returns a pointer to that new <code>page</code>. +</p> + +<p> +Functions can return multiple values. The standard library function +<code>io.ReadFile</code> returns <code>[]byte</code> and <code>os.Error</code>. +In <code>loadPage</code>, error isn't being handled yet; the "blank identifier" +represented by the underscore (<code>_</code>) symbol is used to throw away the +error return value (in essence, assigning the value to nothing). +</p> + +<p> +But what happens if <code>ReadFile</code> encounters an error? For example, +the file might not exist. We should not ignore such errors. Let's modify the +function to return <code>*Page</code> and <code>os.Error</code>. +</p> + +<pre> +!srcextract.bin -src=part1.go -name=loadPage +</pre> + +<p> +Callers of this function can now check the second parameter; if it is +<code>nil</code> then it has successfully loaded a Page. If not, it will be an +<code>os.Error</code> that can be handled by the caller (see the <a +href="http://golang.org/pkg/os/#Error">os package documentation</a> for +details). +</p> + +<p> +At this point we have a simple data structure and the ability to save to and +load from a file. Let's write a <code>main</code> function to test what we've +written: +</p> + +<pre> +!srcextract.bin -src=part1.go -name=main +</pre> + +<p> +After compiling and executing this code, a file named <code>TestPage.txt</code> +would be created, containing the contents of <code>p1</code>. The file would +then be read into the struct <code>p2</code>, and its <code>Body</code> element +printed to the screen. +</p> + +<p> +You can compile and run the program like this: +</p> + +<pre> +$ 8g wiki.go +$ 8l wiki.8 +$ ./8.out +This is a sample page. +</pre> + +<p> +(The <code>8g</code> and <code>8l</code> commands are applicable to +<code>GOARCH=386</code>. If you're on an <code>amd64</code> system, +substitute 6's for the 8's.) +</p> + +<p> +<a href="part1.go">Click here to view the code we've written so far.</a> +</p> + +<h2>Introducing the <code>http</code> package (an interlude)</h2> + +<p> +Here's a full working example of a simple web server: +</p> + +<pre> +!htmlify.bin < http-sample.go +</pre> + +<p> +The <code>main</code> function begins with a call to +<code>http.HandleFunc</code>, which tells the <code>http</code> package to +handle all requests to the web root (<code>"/"</code>) with +<code>handler</code>. +</p> + +<p> +It then calls <code>http.ListenAndServe</code>, specifying that it should +listen on port 8080 on any interface (<code>":8080"</code>). (Don't +worry about its second parameter, <code>nil</code>, for now.) +This function will block until the program is terminated. +</p> + +<p> +The function <code>handler</code> is of the type <code>http.HandlerFunc</code>. +It takes an <code>http.ResponseWriter</code> and an <code>http.Request</code> as +its arguments. +</p> + +<p> +An <code>http.ResponseWriter</code> value assembles the HTTP server's response; by writing +to it, we send data to the HTTP client. +</p> + +<p> +An <code>http.Request</code> is a data structure that represents the client +HTTP request. The string <code>r.URL.Path</code> is the path component +of the request URL. The trailing <code>[1:]</code> means +"create a sub-slice of <code>Path</code> from the 1st character to the end." +This drops the leading "/" from the path name. +</p> + +<p> +If you run this program and access the URL: +</p> +<pre>http://localhost:8080/monkeys</pre> +<p> +the program would present a page containing: +</p> +<pre>Hi there, I love monkeys!</pre> + +<h2>Using <code>http</code> to serve wiki pages</h2> + +<p> +To use the <code>http</code> package, it must be imported: +</p> + +<pre> +import ( + "fmt" + <b>"http"</b> + "io/ioutil" + "os" +) +</pre> + +<p> +Let's create a handler to view a wiki page: +</p> + +<pre> +!srcextract.bin -src=part2.go -name=lenPath + +!srcextract.bin -src=part2.go -name=viewHandler +</pre> + +<p> +First, this function extracts the page title from <code>r.URL.Path</code>, +the path component of the request URL. The global constant +<code>lenPath</code> is the length of the leading <code>"/view/"</code> +component of the request path. +The <code>Path</code> is re-sliced with <code>[lenPath:]</code> to drop the +first 6 characters of the string. This is because the path will invariably +begin with <code>"/view/"</code>, which is not part of the page title. +</p> + +<p> +The function then loads the page data, formats the page with a string of simple +HTML, and writes it to <code>w</code>, the <code>http.ResponseWriter</code>. +</p> + +<p> +Again, note the use of <code>_</code> to ignore the <code>os.Error</code> +return value from <code>loadPage</code>. This is done here for simplicity +and generally considered bad practice. We will attend to this later. +</p> + +<p> +To use this handler, we create a <code>main</code> function that +initializes <code>http</code> using the <code>viewHandler</code> to handle +any requests under the path <code>/view/</code>. +</p> + +<pre> +!srcextract.bin -src=part2.go -name=main +</pre> + +<p> +<a href="part2.go">Click here to view the code we've written so far.</a> +</p> + +<p> +Let's create some page data (as <code>test.txt</code>), compile our code, and +try serving a wiki page: +</p> + +<pre> +$ echo "Hello world" > test.txt +$ 8g wiki.go +$ 8l wiki.8 +$ ./8.out +</pre> + +<p> +With this web server running, a visit to <code><a +href="http://localhost:8080/view/test">http://localhost:8080/view/test</a></code> +should show a page titled "test" containing the words "Hello world". +</p> + +<h2>Editing Pages</h2> + +<p> +A wiki is not a wiki without the ability to edit pages. Let's create two new +handlers: one named <code>editHandler</code> to display an 'edit page' form, +and the other named <code>saveHandler</code> to save the data entered via the +form. +</p> + +<p> +First, we add them to <code>main()</code>: +</p> + +<pre> +!srcextract.bin -src=final-noclosure.go -name=main +</pre> + +<p> +The function <code>editHandler</code> loads the page +(or, if it doesn't exist, create an empty <code>Page</code> struct), +and displays an HTML form. +</p> + +<pre> +!srcextract.bin -src=notemplate.go -name=editHandler +</pre> + +<p> +This function will work fine, but all that hard-coded HTML is ugly. +Of course, there is a better way. +</p> + +<h2>The <code>template</code> package</h2> + +<p> +The <code>template</code> package is part of the Go standard library. +(A new template package is coming; this code lab will be updated soon.) +We can +use <code>template</code> to keep the HTML in a separate file, allowing +us to change the layout of our edit page without modifying the underlying Go +code. +</p> + +<p> +First, we must add <code>template</code> to the list of imports: +</p> + +<pre> +import ( + "http" + "io/ioutil" + "os" + <b>"template"</b> +) +</pre> + +<p> +Let's create a template file containing the HTML form. +Open a new file named <code>edit.html</code>, and add the following lines: +</p> + +<pre> +!htmlify.bin < edit.html +</pre> + +<p> +Modify <code>editHandler</code> to use the template, instead of the hard-coded +HTML: +</p> + +<pre> +!srcextract.bin -src=final-noerror.go -name=editHandler +</pre> + +<p> +The function <code>template.ParseFile</code> will read the contents of +<code>edit.html</code> and return a <code>*template.Template</code>. +</p> + +<p> +The method <code>t.Execute</code> executes the template, writing the +generated HTML to the <code>http.ResponseWriter</code>. +The <code>.Title</code> and <code>.Body</code> dotted identifiers refer to +<code>p.Title</code> and <code>p.Body</code>. +</p> + +<p> +Template directives are enclosed in double curly braces. +The <code>printf "%s" .Body</code> instruction is a function call +that outputs <code>.Body</code> as a string instead of a stream of bytes, +the same as a call to <code>fmt.Printf</code>. +The <code>|html</code> part of each directive pipes the value through the +<code>html</code> formatter before outputting it, which escapes HTML +characters (such as replacing <code>></code> with <code>&gt;</code>), +preventing user data from corrupting the form HTML. +</p> + +<p> +Now that we've removed the <code>fmt.Fprintf</code> statement, we can remove +<code>"fmt"</code> from the <code>import</code> list. +</p> + +<p> +While we're working with templates, let's create a template for our +<code>viewHandler</code> called <code>view.html</code>: +</p> + +<pre> +!htmlify.bin < view.html +</pre> + +<p> +Modify <code>viewHandler</code> accordingly: +</p> + +<pre> +!srcextract.bin -src=final-noerror.go -name=viewHandler +</pre> + +<p> +Notice that we've used almost exactly the same templating code in both +handlers. Let's remove this duplication by moving the templating code +to its own function: +</p> + +<pre> +!srcextract.bin -src=final-template.go -name=viewHandler + +!srcextract.bin -src=final-template.go -name=editHandler + +!srcextract.bin -src=final-template.go -name=renderTemplate +</pre> + +<p> +The handlers are now shorter and simpler. +</p> + +<h2>Handling non-existent pages</h2> + +<p> +What if you visit <code>/view/APageThatDoesntExist</code>? The program will +crash. This is because it ignores the error return value from +<code>loadPage</code>. Instead, if the requested Page doesn't exist, it should +redirect the client to the edit Page so the content may be created: +</p> + +<pre> +!srcextract.bin -src=final-noclosure.go -name=viewHandler +</pre> + +<p> +The <code>http.Redirect</code> function adds an HTTP status code of +<code>http.StatusFound</code> (302) and a <code>Location</code> +header to the HTTP response. +</p> + +<h2>Saving Pages</h2> + +<p> +The function <code>saveHandler</code> will handle the form submission. +</p> + +<pre> +!srcextract.bin -src=final-template.go -name=saveHandler +</pre> + +<p> +The page title (provided in the URL) and the form's only field, +<code>Body</code>, are stored in a new <code>Page</code>. +The <code>save()</code> method is then called to write the data to a file, +and the client is redirected to the <code>/view/</code> page. +</p> + +<p> +The value returned by <code>FormValue</code> is of type <code>string</code>. +We must convert that value to <code>[]byte</code> before it will fit into +the <code>Page</code> struct. We use <code>[]byte(body)</code> to perform +the conversion. +</p> + +<h2>Error handling</h2> + +<p> +There are several places in our program where errors are being ignored. This +is bad practice, not least because when an error does occur the program will +crash. A better solution is to handle the errors and return an error message +to the user. That way if something does go wrong, the server will continue to +function and the user will be notified. +</p> + +<p> +First, let's handle the errors in <code>renderTemplate</code>: +</p> + +<pre> +!srcextract.bin -src=final-parsetemplate.go -name=renderTemplate +</pre> + +<p> +The <code>http.Error</code> function sends a specified HTTP response code +(in this case "Internal Server Error") and error message. +Already the decision to put this in a separate function is paying off. +</p> + +<p> +Now let's fix up <code>saveHandler</code>: +</p> + +<pre> +!srcextract.bin -src=final-noclosure.go -name=saveHandler +</pre> + +<p> +Any errors that occur during <code>p.save()</code> will be reported +to the user. +</p> + +<h2>Template caching</h2> + +<p> +There is an inefficiency in this code: <code>renderTemplate</code> calls +<code>ParseFile</code> every time a page is rendered. +A better approach would be to call <code>ParseFile</code> once for each +template at program initialization, and store the resultant +<code>*Template</code> values in a data structure for later use. +</p> + +<p> +First we create a global map named <code>templates</code> in which to store +our <code>*Template</code> values, keyed by <code>string</code> +(the template name): +</p> + +<pre> +!srcextract.bin -src=final.go -name=templates +</pre> + +<p> +Then we create an <code>init</code> function, which will be called before +<code>main</code> at program initialization. The function +<code>template.Must</code> is a convenience wrapper that panics when passed a +non-nil <code>os.Error</code> value, and otherwise returns the +<code>*Template</code> unaltered. A panic is appropriate here; if the templates +can't be loaded the only sensible thing to do is exit the program. +</p> + +<pre> +!srcextract.bin -src=final.go -name=init +</pre> + +<p> +A <code>for</code> loop is used with a <code>range</code> statement to iterate +over an array constant containing the names of the templates we want parsed. +If we were to add more templates to our program, we would add their names to +that array. +</p> + +<p> +We then modify our <code>renderTemplate</code> function to call +the <code>Execute</code> method on the appropriate <code>Template</code> from +<code>templates</code>: + +<pre> +!srcextract.bin -src=final.go -name=renderTemplate +</pre> + +<h2>Validation</h2> + +<p> +As you may have observed, this program has a serious security flaw: a user +can supply an arbitrary path to be read/written on the server. To mitigate +this, we can write a function to validate the title with a regular expression. +</p> + +<p> +First, add <code>"regexp"</code> to the <code>import</code> list. +Then we can create a global variable to store our validation regexp: +</p> + +<pre> +!srcextract.bin -src=final-noclosure.go -name=titleValidator +</pre> + +<p> +The function <code>regexp.MustCompile</code> will parse and compile the +regular expression, and return a <code>regexp.Regexp</code>. +<code>MustCompile</code> is distinct from <code>Compile</code> in that it will +panic if the expression compilation fails, while <code>Compile</code> returns +an <code>os.Error</code> as a second parameter. +</p> + +<p> +Now, let's write a function that extracts the title string from the request +URL, and tests it against our <code>TitleValidator</code> expression: +</p> + +<pre> +!srcextract.bin -src=final-noclosure.go -name=getTitle +</pre> + +<p> +If the title is valid, it will be returned along with a <code>nil</code> +error value. If the title is invalid, the function will write a +"404 Not Found" error to the HTTP connection, and return an error to the +handler. +</p> + +<p> +Let's put a call to <code>getTitle</code> in each of the handlers: +</p> + +<pre> +!srcextract.bin -src=final-noclosure.go -name=viewHandler + +!srcextract.bin -src=final-noclosure.go -name=editHandler + +!srcextract.bin -src=final-noclosure.go -name=saveHandler +</pre> + +<h2>Introducing Function Literals and Closures</h2> + +<p> +Catching the error condition in each handler introduces a lot of repeated code. +What if we could wrap each of the handlers in a function that does this +validation and error checking? Go's +<a href="http://golang.org/doc/go_spec.html#Function_declarations">function +literals</a> provide a powerful means of abstracting functionality +that can help us here. +</p> + +<p> +First, we re-write the function definition of each of the handlers to accept +a title string: +</p> + +<pre> +func viewHandler(w http.ResponseWriter, r *http.Request, title string) +func editHandler(w http.ResponseWriter, r *http.Request, title string) +func saveHandler(w http.ResponseWriter, r *http.Request, title string) +</pre> + +<p> +Now let's define a wrapper function that <i>takes a function of the above +type</i>, and returns a function of type <code>http.HandlerFunc</code> +(suitable to be passed to the function <code>http.HandleFunc</code>): +</p> + +<pre> +func makeHandler(fn func (http.ResponseWriter, *http.Request, string)) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + // Here we will extract the page title from the Request, + // and call the provided handler 'fn' + } +} +</pre> + +<p> +The returned function is called a closure because it encloses values defined +outside of it. In this case, the variable <code>fn</code> (the single argument +to <code>makeHandler</code>) is enclosed by the closure. The variable +<code>fn</code> will be one of our save, edit, or view handlers. +</p> + +<p> +Now we can take the code from <code>getTitle</code> and use it here +(with some minor modifications): +</p> + +<pre> +!srcextract.bin -src=final.go -name=makeHandler +</pre> + +<p> +The closure returned by <code>makeHandler</code> is a function that takes +an <code>http.ResponseWriter</code> and <code>http.Request</code> (in other +words, an <code>http.HandlerFunc</code>). +The closure extracts the <code>title</code> from the request path, and +validates it with the <code>TitleValidator</code> regexp. If the +<code>title</code> is invalid, an error will be written to the +<code>ResponseWriter</code> using the <code>http.NotFound</code> function. +If the <code>title</code> is valid, the enclosed handler function +<code>fn</code> will be called with the <code>ResponseWriter</code>, +<code>Request</code>, and <code>title</code> as arguments. +</p> + +<p> +Now we can wrap the handler functions with <code>makeHandler</code> in +<code>main</code>, before they are registered with the <code>http</code> +package: +</p> + +<pre> +!srcextract.bin -src=final.go -name=main +</pre> + +<p> +Finally we remove the calls to <code>getTitle</code> from the handler functions, +making them much simpler: +</p> + +<pre> +!srcextract.bin -src=final.go -name=viewHandler + +!srcextract.bin -src=final.go -name=editHandler + +!srcextract.bin -src=final.go -name=saveHandler +</pre> + +<h2>Try it out!</h2> + +<p> +<a href="final.go">Click here to view the final code listing.</a> +</p> + +<p> +Recompile the code, and run the app: +</p> + +<pre> +$ 8g wiki.go +$ 8l wiki.8 +$ ./8.out +</pre> + +<p> +Visiting <a href="http://localhost:8080/view/ANewPage">http://localhost:8080/view/ANewPage</a> +should present you with the page edit form. You should then be able to +enter some text, click 'Save', and be redirected to the newly created page. +</p> + +<h2>Other tasks</h2> + +<p> +Here are some simple tasks you might want to tackle on your own: +</p> + +<ul> +<li>Store templates in <code>tmpl/</code> and page data in <code>data/</code>. +<li>Add a handler to make the web root redirect to + <code>/view/FrontPage</code>.</li> +<li>Spruce up the page templates by making them valid HTML and adding some + CSS rules.</li> +<li>Implement inter-page linking by converting instances of + <code>[PageName]</code> to <br> + <code><a href="/view/PageName">PageName</a></code>. + (hint: you could use <code>regexp.ReplaceAllFunc</code> to do this) + </li> +</ul> diff --git a/doc/codereview_with_mq.html b/doc/codereview_with_mq.html new file mode 100644 index 000000000..33f415f13 --- /dev/null +++ b/doc/codereview_with_mq.html @@ -0,0 +1,113 @@ +<!-- Using Mercurial Queues with Codereview --> + +<h2 id="Introduction">Introduction</h2> + +<p> +The Mercurial Queues extension (<code>mq</code>) provides a mechanism for +managing patches on top of a Mercurial repository and is described in detail +in Chapters +<a href="http://hgbook.red-bean.com/read/managing-change-with-mercurial-queues.html">12</a> +and <a href="http://hgbook.red-bean.com/read/advanced-uses-of-mercurial-queues.html">13</a> +of <a href="http://hgbook.red-bean.com/read/">Mercurial: The Definitive Guide</a>. +This document explains how to use <code>mq</code> in conjunction +with the <code>codereview</code> Mercurial extension described in the +instructions for <a href="contribute.html">contributing to the Go project</a>. +It assumes you have read those instructions. +</p> + +<h2>Configuration</h2> + +<p> +To enable <code>mq</code> edit either <code>$HOME/.hgrc</code> (to enable it +for all of your repositories) or <code>$GOROOT/.hg/hgrc</code> (to enable it for the +repository at <code>$GOROOT</code>) to add:</p> + +<pre> +[extensions] +mq= +</pre> + +<p> +Since pulling, pushing, updating and committing while <code>mq</code> patches +are applied can damage your repository or a remote one, add these lines to +prevent that case: +</p> + +<pre> +[hooks] +# Prevent "hg pull" if MQ patches are applied. +prechangegroup.mq-no-pull = ! hg qtop > /dev/null 2>&1 +# Prevent "hg push" if MQ patches are applied. +preoutgoing.mq-no-push = ! hg qtop > /dev/null 2>&1 +# Prevent "hg update" if MQ patches are applied. +preupdate.mq-no-update = ! hg qtop > /dev/null 2>&1 +</pre> + +<h2>Making a change</h2> + +<p> +The entire checked-out tree is writable and you can use <code>mq</code>, +as documented in Chapter +<a href="http://hgbook.red-bean.com/read/managing-change-with-mercurial-queues.html">12</a> +of "The Guide", +to implement your change as a single patch or a series of patches. + +</p> + +<p>When you are ready to send a change out for review, run</p> + +<pre> +$ hg change +</pre> + +<p>from any directory in your Go repository with all of the <code>mq</code> patches relevant to your +change applied and then proceed as instructed in <a href="contribute.html">contributing +to the Go project</a>. +</p> + +<p> +The change number reported by <code>hg change</code>, preceded by a <code>+</code>, +can be used as an <code>mq</code> patch guard to assist in controlling which patches +are applied as described in Chapter +<a href="http://hgbook.red-bean.com/read/advanced-uses-of-mercurial-queues.html">13</a> +of "The Guide". +For example, the command: +</p> + +<pre> +for p in $(hg qapplied); do hg qguard $p +99999; done +</pre> + +<p> +will apply the guard <code>+99999</code> guard to all currently applied <code>mq</code> +patches. +</p> + +<h2>Synchronizing your client</h2> + +<p>While you were working, others might have submitted changes +to the repository and, as explained in <a href="contribute.html">contributing +to the Go project</a>, it is necessary to synchronize your repository using +<code>hg sync</code>before sending your change list for review. +Because <code>hg sync</code> runs <code>hg pull -u</code>, +you should not run <code>hg sync</code> while <code>mq</code> patches are +applied. Instead +pop all your patches before running <code>hg sync</code> and reapply them after +it has completed. +</p> + +<p> +When reapplying the patches, you may need to resolve conflicts +as described in <a href="contribute.html">contributing to the Go project</a>. +</p> + +<h2>Mailing the change for review</h2> + +<p> +You should have all of the <code>mq</code> patches relevant to your +change applied when you run <code>hg mail</code>. + +<h2>Submitting the change after the review</h2> + +If you are a committer, you should have all of the <code>mq</code> patches relevant to your +change applied when you run <code>hg commit</code>. diff --git a/doc/codewalk/codewalk.css b/doc/codewalk/codewalk.css new file mode 100644 index 000000000..a0814e4d2 --- /dev/null +++ b/doc/codewalk/codewalk.css @@ -0,0 +1,234 @@ +/* + Copyright 2010 The Go Authors. All rights reserved. + Use of this source code is governed by a BSD-style + license that can be found in the LICENSE file. +*/ + +#codewalk-main { + text-align: left; + width: 100%; + overflow: auto; +} + +#code-display { + border: 0; + width: 100%; +} + +.setting { + font-size: 8pt; + color: #888888; + padding: 5px; +} + +.hotkey { + text-decoration: underline; +} + +/* Style for Comments (the left-hand column) */ + +#comment-column { + margin: 0pt; + width: 30%; +} + +#comment-column.right { + float: right; +} + +#comment-column.left { + float: left; +} + +#comment-area { + overflow-x: hidden; + overflow-y: auto; +} + +.comment { + cursor: pointer; + font-size: 16px; + border: 2px solid #ba9836; + margin-bottom: 10px; + margin-right: 10px; /* yes, for both .left and .right */ +} + +.comment:last-child { + margin-bottom: 0px; +} + +.right .comment { + margin-left: 10px; +} + +.right .comment.first { +} + +.right .comment.last { +} + +.left .comment.first { +} + +.left .comment.last { +} + +.comment.selected { + border-color: #99b2cb; +} + +.right .comment.selected { + border-left-width: 12px; + margin-left: 0px; +} + +.left .comment.selected { + border-right-width: 12px; + margin-right: 0px; +} + +.comment-link { + display: none; +} + +.comment-title { + font-size: small; + font-weight: bold; + background-color: #fffff0; + padding-right: 10px; + padding-left: 10px; + padding-top: 5px; + padding-bottom: 5px; +} + +.right .comment-title { +} + +.left .comment-title { +} + +.comment.selected .comment-title { + background-color: #f8f8ff; +} + +.comment-text { + overflow: auto; + padding-left: 10px; + padding-right: 10px; + padding-top: 10px; + padding-bottom: 5px; + font-size: small; + line-height: 1.3em; +} + +.comment-text p { + margin-top: 0em; + margin-bottom: 0.5em; +} + +.comment-text p:last-child { + margin-bottom: 0em; +} + +.file-name { + font-size: x-small; + padding-top: 0px; + padding-bottom: 5px; +} + +.hidden-filepaths .file-name { + display: none; +} + +.path-dir { + color: #555; +} + +.path-file { + color: #555; +} + + +/* Style for Code (the right-hand column) */ + +/* Wrapper for the code column to make widths get calculated correctly */ +#code-column { + display: block; + position: relative; + margin: 0pt; + width: 70%; +} + +#code-column.left { + float: left; +} + +#code-column.right { + float: right; +} + +#code-area { + background-color: #f8f8ff; + border: 2px solid #99b2cb; + padding: 5px; +} + +.left #code-area { + margin-right: -1px; +} + +.right #code-area { + margin-left: -1px; +} + +#code-header { + margin-bottom: 5px; +} + +#code { + background-color: white; +} + +code { + font-size: 100%; +} + +.codewalkhighlight { + font-weight: bold; + background-color: #f8f8ff; +} + +#code-display { + margin-top: 0px; + margin-bottom: 0px; +} + +#sizer { + position: absolute; + cursor: col-resize; + left: 0px; + top: 0px; + width: 8px; +} + +/* Style for options (bottom strip) */ + +#code-options { + display: none; +} + +#code-options > span { + padding-right: 20px; +} + +#code-options .selected { + border-bottom: 1px dotted; +} + +#comment-options { + text-align: center; +} + +div#content { + padding-bottom: 0em; +} diff --git a/doc/codewalk/codewalk.js b/doc/codewalk/codewalk.js new file mode 100644 index 000000000..f780bc7a5 --- /dev/null +++ b/doc/codewalk/codewalk.js @@ -0,0 +1,305 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +/** + * A class to hold information about the Codewalk Viewer. + * @param {jQuery} context The top element in whose context the viewer should + * operate. It will not touch any elements above this one. + * @constructor + */ + var CodewalkViewer = function(context) { + this.context = context; + + /** + * The div that contains all of the comments and their controls. + */ + this.commentColumn = this.context.find('#comment-column'); + + /** + * The div that contains the comments proper. + */ + this.commentArea = this.context.find('#comment-area'); + + /** + * The div that wraps the iframe with the code, as well as the drop down menu + * listing the different files. + * @type {jQuery} + */ + this.codeColumn = this.context.find('#code-column'); + + /** + * The div that contains the code but excludes the options strip. + * @type {jQuery} + */ + this.codeArea = this.context.find('#code-area'); + + /** + * The iframe that holds the code (from Sourcerer). + * @type {jQuery} + */ + this.codeDisplay = this.context.find('#code-display'); + + /** + * The overlaid div used as a grab handle for sizing the code/comment panes. + * @type {jQuery} + */ + this.sizer = this.context.find('#sizer'); + + /** + * The full-screen overlay that ensures we don't lose track of the mouse + * while dragging. + * @type {jQuery} + */ + this.overlay = this.context.find('#overlay'); + + /** + * The hidden input field that we use to hold the focus so that we can detect + * shortcut keypresses. + * @type {jQuery} + */ + this.shortcutInput = this.context.find('#shortcut-input'); + + /** + * The last comment that was selected. + * @type {jQuery} + */ + this.lastSelected = null; +}; + +/** + * Minimum width of the comments or code pane, in pixels. + * @type {number} + */ +CodewalkViewer.MIN_PANE_WIDTH = 200; + +/** + * Navigate the code iframe to the given url and update the code popout link. + * @param {string} url The target URL. + * @param {Object} opt_window Window dependency injection for testing only. + */ +CodewalkViewer.prototype.navigateToCode = function(url, opt_window) { + if (!opt_window) opt_window = window; + // Each iframe is represented by two distinct objects in the DOM: an iframe + // object and a window object. These do not expose the same capabilities. + // Here we need to get the window representation to get the location member, + // so we access it directly through window[] since jQuery returns the iframe + // representation. + // We replace location rather than set so as not to create a history for code + // navigation. + opt_window['code-display'].location.replace(url); + var k = url.indexOf('&'); + if (k != -1) url = url.slice(0, k); + k = url.indexOf('fileprint='); + if (k != -1) url = url.slice(k+10, url.length); + this.context.find('#code-popout-link').attr('href', url); +}; + +/** + * Selects the first comment from the list and forces a refresh of the code + * view. + */ +CodewalkViewer.prototype.selectFirstComment = function() { + // TODO(rsc): handle case where there are no comments + var firstSourcererLink = this.context.find('.comment:first'); + this.changeSelectedComment(firstSourcererLink); +}; + +/** + * Sets the target on all links nested inside comments to be _blank. + */ +CodewalkViewer.prototype.targetCommentLinksAtBlank = function() { + this.context.find('.comment a[href], #description a[href]').each(function() { + if (!this.target) this.target = '_blank'; + }); +}; + +/** + * Installs event handlers for all the events we care about. + */ +CodewalkViewer.prototype.installEventHandlers = function() { + var self = this; + + this.context.find('.comment') + .click(function(event) { + if (jQuery(event.target).is('a[href]')) return true; + self.changeSelectedComment(jQuery(this)); + return false; + }); + + this.context.find('#code-selector') + .change(function() {self.navigateToCode(jQuery(this).val());}); + + this.context.find('#description-table .quote-feet.setting') + .click(function() {self.toggleDescription(jQuery(this)); return false;}); + + this.sizer + .mousedown(function(ev) {self.startSizerDrag(ev); return false;}); + this.overlay + .mouseup(function(ev) {self.endSizerDrag(ev); return false;}) + .mousemove(function(ev) {self.handleSizerDrag(ev); return false;}); + + this.context.find('#prev-comment') + .click(function() { + self.changeSelectedComment(self.lastSelected.prev()); return false; + }); + + this.context.find('#next-comment') + .click(function() { + self.changeSelectedComment(self.lastSelected.next()); return false; + }); + + // Workaround for Firefox 2 and 3, which steal focus from the main document + // whenever the iframe content is (re)loaded. The input field is not shown, + // but is a way for us to bring focus back to a place where we can detect + // keypresses. + this.context.find('#code-display') + .load(function(ev) {self.shortcutInput.focus();}); + + jQuery(document).keypress(function(ev) { + switch(ev.which) { + case 110: // 'n' + self.changeSelectedComment(self.lastSelected.next()); + return false; + case 112: // 'p' + self.changeSelectedComment(self.lastSelected.prev()); + return false; + default: // ignore + } + }); + + window.onresize = function() {self.updateHeight();}; +}; + +/** + * Starts dragging the pane sizer. + * @param {Object} ev The mousedown event that started us dragging. + */ +CodewalkViewer.prototype.startSizerDrag = function(ev) { + this.initialCodeWidth = this.codeColumn.width(); + this.initialCommentsWidth = this.commentColumn.width(); + this.initialMouseX = ev.pageX; + this.overlay.show(); +}; + +/** + * Handles dragging the pane sizer. + * @param {Object} ev The mousemove event updating dragging position. + */ +CodewalkViewer.prototype.handleSizerDrag = function(ev) { + var delta = ev.pageX - this.initialMouseX; + if (this.codeColumn.is('.right')) delta = -delta; + var proposedCodeWidth = this.initialCodeWidth + delta; + var proposedCommentWidth = this.initialCommentsWidth - delta; + var mw = CodewalkViewer.MIN_PANE_WIDTH; + if (proposedCodeWidth < mw) delta = mw - this.initialCodeWidth; + if (proposedCommentWidth < mw) delta = this.initialCommentsWidth - mw; + proposedCodeWidth = this.initialCodeWidth + delta; + proposedCommentWidth = this.initialCommentsWidth - delta; + // If window is too small, don't even try to resize. + if (proposedCodeWidth < mw || proposedCommentWidth < mw) return; + this.codeColumn.width(proposedCodeWidth); + this.commentColumn.width(proposedCommentWidth); + this.options.codeWidth = parseInt( + this.codeColumn.width() / + (this.codeColumn.width() + this.commentColumn.width()) * 100); + this.context.find('#code-column-width').text(this.options.codeWidth + '%'); +}; + +/** + * Ends dragging the pane sizer. + * @param {Object} ev The mouseup event that caused us to stop dragging. + */ +CodewalkViewer.prototype.endSizerDrag = function(ev) { + this.overlay.hide(); + this.updateHeight(); +}; + +/** + * Toggles the Codewalk description between being shown and hidden. + * @param {jQuery} target The target that was clicked to trigger this function. + */ +CodewalkViewer.prototype.toggleDescription = function(target) { + var description = this.context.find('#description'); + description.toggle(); + target.find('span').text(description.is(':hidden') ? 'show' : 'hide'); + this.updateHeight(); +}; + +/** + * Changes the side of the window on which the code is shown and saves the + * setting in a cookie. + * @param {string?} codeSide The side on which the code should be, either + * 'left' or 'right'. + */ +CodewalkViewer.prototype.changeCodeSide = function(codeSide) { + var commentSide = codeSide == 'left' ? 'right' : 'left'; + this.context.find('#set-code-' + codeSide).addClass('selected'); + this.context.find('#set-code-' + commentSide).removeClass('selected'); + // Remove previous side class and add new one. + this.codeColumn.addClass(codeSide).removeClass(commentSide); + this.commentColumn.addClass(commentSide).removeClass(codeSide); + this.sizer.css(codeSide, 'auto').css(commentSide, 0); + this.options.codeSide = codeSide; +}; + +/** + * Adds selected class to newly selected comment, removes selected style from + * previously selected comment, changes drop down options so that the correct + * file is selected, and updates the code popout link. + * @param {jQuery} target The target that was clicked to trigger this function. + */ +CodewalkViewer.prototype.changeSelectedComment = function(target) { + var currentFile = target.find('.comment-link').attr('href'); + if (!currentFile) return; + + if (!(this.lastSelected && this.lastSelected.get(0) === target.get(0))) { + if (this.lastSelected) this.lastSelected.removeClass('selected'); + target.addClass('selected'); + this.lastSelected = target; + var targetTop = target.position().top; + var parentTop = target.parent().position().top; + if (targetTop + target.height() > parentTop + target.parent().height() || + targetTop < parentTop) { + var delta = targetTop - parentTop; + target.parent().animate( + {'scrollTop': target.parent().scrollTop() + delta}, + Math.max(delta / 2, 200), 'swing'); + } + var fname = currentFile.match(/(?:select=|fileprint=)\/[^&]+/)[0]; + fname = fname.slice(fname.indexOf('=')+2, fname.length); + this.context.find('#code-selector').val(fname); + this.context.find('#prev-comment').toggleClass( + 'disabled', !target.prev().length); + this.context.find('#next-comment').toggleClass( + 'disabled', !target.next().length); + } + + // Force original file even if user hasn't changed comments since they may + // have nagivated away from it within the iframe without us knowing. + this.navigateToCode(currentFile); +}; + +/** + * Updates the viewer by changing the height of the comments and code so that + * they fit within the height of the window. The function is typically called + * after the user changes the window size. + */ +CodewalkViewer.prototype.updateHeight = function() { + var windowHeight = jQuery(window).height() - 5 // GOK + var areaHeight = windowHeight - this.codeArea.offset().top + var footerHeight = this.context.find('#footer').outerHeight(true) + this.commentArea.height(areaHeight - footerHeight - this.context.find('#comment-options').outerHeight(true)) + var codeHeight = areaHeight - footerHeight - 15 // GOK + this.codeArea.height(codeHeight) + this.codeDisplay.height(codeHeight - this.codeDisplay.offset().top + this.codeArea.offset().top); + this.sizer.height(codeHeight); +}; + +jQuery(document).ready(function() { + var viewer = new CodewalkViewer(jQuery()); + viewer.selectFirstComment(); + viewer.targetCommentLinksAtBlank(); + viewer.installEventHandlers(); + viewer.updateHeight(); +}); diff --git a/doc/codewalk/codewalk.xml b/doc/codewalk/codewalk.xml new file mode 100644 index 000000000..9cd8361e8 --- /dev/null +++ b/doc/codewalk/codewalk.xml @@ -0,0 +1,124 @@ +<codewalk title="How to Write a Codewalk"> + +<step title="Introduction" src="doc/codewalk/codewalk.xml"> + A codewalk is a guided tour through a piece of code. + It consists of a sequence of steps, each typically explaining + a highlighted section of code. + <br/><br/> + + The <a href="/cmd/godoc">godoc</a> web server translates + an XML file like the one in the main window pane into the HTML + page that you're viewing now. + <br/><br/> + + The codewalk with URL path <code>/doc/codewalk/</code><i>name</i> + is loaded from the input file <code>$GOROOT/doc/codewalk/</code><i>name</i><code>.xml</code>. + <br/><br/> + + This codewalk explains how to write a codewalk by examining + its own source code, + <code><a href="/doc/codewalk/codewalk.xml">$GOROOT/doc/codewalk/codewalk.xml</a></code>, + shown in the main window pane to the left. +</step> + +<step title="Title" src="doc/codewalk/codewalk.xml:/title=/"> + The codewalk input file is an XML file containing a single + <code><codewalk></code> element. + That element's <code>title</code> attribute gives the title + that is used both on the codewalk page and in the codewalk list. +</step> + +<step title="Steps" src="doc/codewalk/codewalk.xml:/<step/,/step>/"> + Each step in the codewalk is a <code><step></code> element + nested inside the main <code><codewalk></code>. + The step element's <code>title</code> attribute gives the step's title, + which is shown in a shaded bar above the main step text. + The element's <code>src</code> attribute specifies the source + code to show in the main window pane and, optionally, a range of + lines to highlight. + <br/><br/> + + The first step in this codewalk does not highlight any lines: + its <code>src</code> is just a file name. +</step> + +<step title="Specifiying a source line" src='doc/codewalk/codewalk.xml:/title="Title"/'> + The most complex part of the codewalk specification is + saying what lines to highlight. + Instead of ordinary line numbers, + the codewalk uses an address syntax that makes it possible + to describe the match by its content. + As the file gets edited, this descriptive address has a better + chance to continue to refer to the right section of the file. + <br/><br/> + + To specify a source line, use a <code>src</code> attribute of the form + <i>filename</i><code>:</code><i>address</i>, + where <i>address</i> is an address in the syntax used by the text editors <i>sam</i> and <i>acme</i>. + <br/><br/> + + The simplest address is a single regular expression. + The highlighted line in the main window pane shows that the + address for the “Title” step was <code>/title=/</code>, + which matches the first instance of that <a href="/pkg/regexp">regular expression</a> (<code>title=</code>) in the file. +</step> + +<step title="Specifying a source range" src='doc/codewalk/codewalk.xml:/title="Steps"/'> + To highlight a range of source lines, the simplest address to use is + a pair of regular expressions + <code>/</code><i>regexp1</i><code>/,/</code><i>regexp2</i><code>/</code>. + The highlight begins with the line containing the first match for <i>regexp1</i> + and ends with the line containing the first match for <i>regexp2</i> + after the end of the match for <i>regexp1</i>. + Ignoring the HTML quoting, + The line containing the first match for <i>regexp1</i> will be the first one highlighted, + and the line containing the first match for <i>regexp2</i>. + <br/><br/> + + The address <code>/<step/,/step>/</code> looks for the first instance of + <code><step</code> in the file, and then starting after that point, + looks for the first instance of <code>step></code>. + (Click on the “Steps” step above to see the highlight in action.) + Note that the <code><</code> and <code>></code> had to be written + using XML escapes in order to be valid XML. +</step> + +<step title="Advanced addressing" src="doc/codewalk/codewalk.xml:/Advanced/,/step>/"> + The <code>/</code><i>regexp</i><code>/</code> + and <code>/</code><i>regexp1</i><code>/,/</code><i>regexp2</i><code>/</code> + forms suffice for most highlighting. + <br/><br/> + + The full address syntax is summarized in this table + (an excerpt of Table II from + <a href="http://plan9.bell-labs.com/sys/doc/sam/sam.html">The text editor <code>sam</code></a>): + <br/><br/> + + <table> + <tr><td colspan="2"><b>Simple addresses</b></td></tr> + <tr><td><code>#</code><i>n</i></td> + <td>The empty string after character <i>n</i></td></tr> + <tr><td><i>n</i></td> + <td>Line <i>n</i></td></tr> + <tr><td><code>/</code><i>regexp</i><code>/</code></td> + <td>The first following match of the regular expression</td></tr> + <!-- not supported (yet?) + <tr><td><code>–/</code><i>regexp</i><code>/</code></td> + <td>The first previous match of the regular expression</td></tr> + --> + <tr><td><code>$</code></td> + <td>The null string at the end of the file</td></tr> + + <tr><td colspan="2"><b>Compound addresses</b></td></tr> + <tr><td><i>a1</i><code>+</code><i>a2</i></td> + <td>The address <i>a2</i> evaluated starting at the right of <i>a1</i></td></tr> + <tr><td><i>a1</i><code>-</code><i>a2</i></td> + <td>The address <i>a2</i> evaluated in the reverse direction starting at the left of <i>a1</i></td></tr> + <tr><td><i>a1</i><code>,</code><i>a2</i></td> + <td>From the left of <i>a1</i> to the right of <i>a2</i> (default <code>0,$</code>).</td></tr> + </table> +</step> + + + +</codewalk> diff --git a/doc/codewalk/functions.xml b/doc/codewalk/functions.xml new file mode 100644 index 000000000..986a017e1 --- /dev/null +++ b/doc/codewalk/functions.xml @@ -0,0 +1,115 @@ +<codewalk title="First-Class Functions in Go"> + +<step title="Introduction" src="doc/codewalk/pig.go"> + Go supports first class functions, higher-order functions, user-defined + function types, function literals, closures, and multiple return values. + <br/><br/> + + This rich feature set supports a functional programming style in a strongly + typed language. + <br/><br/> + + In this codewalk we will look at a simple program that simulates a dice game + called <a href="http://en.wikipedia.org/wiki/Pig_(dice)">Pig</a> and evaluates + basic strategies. +</step> + +<step title="Game overview" src="doc/codewalk/pig.go:/\/\/ A score/,/thisTurn int\n}/"> + Pig is a two-player game played with a 6-sided die. Each turn, you may roll or stay. + <ul> + <li> If you roll a 1, you lose all points for your turn and play passes to + your opponent. Any other roll adds its value to your turn score. </li> + <li> If you stay, your turn score is added to your total score, and play passes + to your opponent. </li> + </ul> + + The first person to reach 100 total points wins. + <br/><br/> + + The <code>score</code> type stores the scores of the current and opposing + players, in addition to the points accumulated during the current turn. +</step> + +<step title="User-defined function types" src="doc/codewalk/pig.go:/\/\/ An action/,/bool\)/"> + In Go, functions can be passed around just like any other value. A function's + type signature describes the types of its arguments and return values. + <br/><br/> + + The <code>action</code> type is a function that takes a <code>score</code> + and returns the resulting <code>score</code> and whether the current turn is + over. + <br/><br/> + + If the turn is over, the <code>player</code> and <code>opponent</code> fields + in the resulting <code>score</code> should be swapped, as it is now the other player's + turn. +</step> + +<step title="Multiple return values" src="doc/codewalk/pig.go:/\/\/ roll returns/,/stay.*true\n}/"> + Go functions can return multiple values. + <br/><br/> + + The functions <code>roll</code> and <code>stay</code> each return a pair of + values. They also match the <code>action</code> type signature. These + <code>action</code> functions define the rules of Pig. +</step> + +<step title="Higher-order functions" src="doc/codewalk/pig.go:/\/\/ A strategy/,/action\n/"> + A function can use other functions as arguments and return values. + <br/><br/> + + A <code>strategy</code> is a function that takes a <code>score</code> as input + and returns an <code>action</code> to perform. <br/> + (Remember, an <code>action</code> is itself a function.) +</step> + +<step title="Function literals and closures" src="doc/codewalk/pig.go:/return func/,/return roll\n\t}/"> + Anonymous functions can be declared in Go, as in this example. Function + literals are closures: they inherit the scope of the function in which they + are declared. + <br/><br/> + + One basic strategy in Pig is to continue rolling until you have accumulated at + least k points in a turn, and then stay. The argument <code>k</code> is + enclosed by this function literal, which matches the <code>strategy</code> type + signature. +</step> + +<step title="Simulating games" src="doc/codewalk/pig.go:/\/\/ play/,/currentPlayer\n}/"> + We simulate a game of Pig by calling an <code>action</code> to update the + <code>score</code> until one player reaches 100 points. Each + <code>action</code> is selected by calling the <code>strategy</code> function + associated with the current player. +</step> + +<step title="Comparing functions" src="doc/codewalk/pig.go:/if action/,/currentPlayer\)\)\n\t\t}/"> + Functions can be compared for equality in Go. From the + <a href="http://golang.org/doc/go_spec.html#Comparison_operators">language specification</a>: + Function values are equal if they refer to the same function or if both are <code>nil</code>. + <br/><br/> + + We enforce that a <code>strategy</code> function can only return a legal + <code>action</code>: either <code>roll</code> or <code>stay</code>. +</step> + +<step title="Simulating a tournament" src="doc/codewalk/pig.go:/\/\/ roundRobin/,/gamesPerStrategy\n}/"> + The <code>roundRobin</code> function simulates a tournament and tallies wins. + Each strategy plays each other strategy <code>gamesPerSeries</code> times. +</step> + +<step title="Variadic function declarations" src="doc/codewalk/pig.go:/\/\/ ratioS/,/string {/"> + Variadic functions like <code>ratioString</code> take a variable number of + arguments. These arguments are available as a slice inside the function. +</step> + +<step title="Simulation results" src="doc/codewalk/pig.go:/func main/,/\n}/"> + The <code>main</code> function defines 100 basic strategies, simulates a round + robin tournament, and then prints the win/loss record of each strategy. + <br/><br/> + + Among these strategies, staying at 25 is best, but the <a + href="http://www.google.com/search?q=optimal+play+pig">optimal strategy for + Pig</a> is much more complex. +</step> + +</codewalk> diff --git a/doc/codewalk/markov.go b/doc/codewalk/markov.go new file mode 100644 index 000000000..959c2b158 --- /dev/null +++ b/doc/codewalk/markov.go @@ -0,0 +1,130 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +/* +Generating random text: a Markov chain algorithm + +Based on the program presented in the "Design and Implementation" chapter +of The Practice of Programming (Kernighan and Pike, Addison-Wesley 1999). +See also Computer Recreations, Scientific American 260, 122 - 125 (1989). + +A Markov chain algorithm generates text by creating a statistical model of +potential textual suffixes for a given prefix. Consider this text: + + I am not a number! I am a free man! + +Our Markov chain algorithm would arrange this text into this set of prefixes +and suffixes, or "chain": (This table assumes a prefix length of two words.) + + Prefix Suffix + + "" "" I + "" I am + I am a + I am not + a free man! + am a free + am not a + a number! I + number! I am + not a number! + +To generate text using this table we select an initial prefix ("I am", for +example), choose one of the suffixes associated with that prefix at random +with probability determined by the input statistics ("a"), +and then create a new prefix by removing the first word from the prefix +and appending the suffix (making the new prefix is "am a"). Repeat this process +until we can't find any suffixes for the current prefix or we exceed the word +limit. (The word limit is necessary as the chain table may contain cycles.) + +Our version of this program reads text from standard input, parsing it into a +Markov chain, and writes generated text to standard output. +The prefix and output lengths can be specified using the -prefix and -words +flags on the command-line. +*/ +package main + +import ( + "bufio" + "flag" + "fmt" + "io" + "os" + "rand" + "strings" + "time" +) + +// Prefix is a Markov chain prefix of one or more words. +type Prefix []string + +// String returns the Prefix as a string (for use as a map key). +func (p Prefix) String() string { + return strings.Join(p, " ") +} + +// Shift removes the first word from the Prefix and appends the given word. +func (p Prefix) Shift(word string) { + copy(p, p[1:]) + p[len(p)-1] = word +} + +// Chain contains a map ("chain") of prefixes to a list of suffixes. +// A prefix is a string of prefixLen words joined with spaces. +// A suffix is a single word. A prefix can have multiple suffixes. +type Chain struct { + chain map[string][]string + prefixLen int +} + +// NewChain returns a new Chain with prefixes of prefixLen words. +func NewChain(prefixLen int) *Chain { + return &Chain{make(map[string][]string), prefixLen} +} + +// Build reads text from the provided Reader and +// parses it into prefixes and suffixes that are stored in Chain. +func (c *Chain) Build(r io.Reader) { + br := bufio.NewReader(r) + p := make(Prefix, c.prefixLen) + for { + var s string + if _, err := fmt.Fscan(br, &s); err != nil { + break + } + key := p.String() + c.chain[key] = append(c.chain[key], s) + p.Shift(s) + } +} + +// Generate returns a string of at most n words generated from Chain. +func (c *Chain) Generate(n int) string { + p := make(Prefix, c.prefixLen) + var words []string + for i := 0; i < n; i++ { + choices := c.chain[p.String()] + if len(choices) == 0 { + break + } + next := choices[rand.Intn(len(choices))] + words = append(words, next) + p.Shift(next) + } + return strings.Join(words, " ") +} + +func main() { + // Register command-line flags. + numWords := flag.Int("words", 100, "maximum number of words to print") + prefixLen := flag.Int("prefix", 2, "prefix length in words") + + flag.Parse() // Parse command-line flags. + rand.Seed(time.Nanoseconds()) // Seed the random number generator. + + c := NewChain(*prefixLen) // Initialize a new Chain. + c.Build(os.Stdin) // Build chains from standard input. + text := c.Generate(*numWords) // Generate text. + fmt.Println(text) // Write text to standard output. +} diff --git a/doc/codewalk/markov.xml b/doc/codewalk/markov.xml new file mode 100644 index 000000000..a89b4d0ce --- /dev/null +++ b/doc/codewalk/markov.xml @@ -0,0 +1,308 @@ +<!-- +Copyright 2011 The Go Authors. All rights reserved. +Use of this source code is governed by a BSD-style +license that can be found in the LICENSE file. +--> + +<codewalk title="Generating arbitrary text: a Markov chain algorithm"> + +<step title="Introduction" src="doc/codewalk/markov.go:/Generating/,/line\./"> + This codewalk describes a program that generates random text using + a Markov chain algorithm. The package comment describes the algorithm + and the operation of the program. Please read it before continuing. +</step> + +<step title="Modeling Markov chains" src="doc/codewalk/markov.go:/ chain/"> + A chain consists of a prefix and a suffix. Each prefix is a set + number of words, while a suffix is a single word. + A prefix can have an arbitrary number of suffixes. + To model this data, we use a <code>map[string][]string</code>. + Each map key is a prefix (a <code>string</code>) and its values are + lists of suffixes (a slice of strings, <code>[]string</code>). + <br/><br/> + Here is the example table from the package comment + as modeled by this data structure: + <pre> +map[string][]string{ + " ": {"I"}, + " I": {"am"}, + "I am": {"a", "not"}, + "a free": {"man!"}, + "am a": {"free"}, + "am not": {"a"}, + "a number!": {"I"}, + "number! I": {"am"}, + "not a": {"number!"}, +}</pre> + While each prefix consists of multiple words, we + store prefixes in the map as a single <code>string</code>. + It would seem more natural to store the prefix as a + <code>[]string</code>, but we can't do this with a map because the + key type of a map must implement equality (and slices do not). + <br/><br/> + Therefore, in most of our code we will model prefixes as a + <code>[]string</code> and join the strings together with a space + to generate the map key: + <pre> +Prefix Map key + +[]string{"", ""} " " +[]string{"", "I"} " I" +[]string{"I", "am"} "I am" +</pre> +</step> + +<step title="The Chain struct" src="doc/codewalk/markov.go:/type Chain/,/}/"> + The complete state of the chain table consists of the table itself and + the word length of the prefixes. The <code>Chain</code> struct stores + this data. +</step> + +<step title="The NewChain constructor function" src="doc/codewalk/markov.go:/func New/,/}/"> + The <code>Chain</code> struct has two unexported fields (those that + do not begin with an upper case character), and so we write a + <code>NewChain</code> constructor function that initializes the + <code>chain</code> map with <code>make</code> and sets the + <code>prefixLen</code> field. + <br/><br/> + This is constructor function is not strictly necessary as this entire + program is within a single package (<code>main</code>) and therefore + there is little practical difference between exported and unexported + fields. We could just as easily write out the contents of this function + when we want to construct a new Chain. + But using these unexported fields is good practice; it clearly denotes + that only methods of Chain and its constructor function should access + those fields. Also, structuring <code>Chain</code> like this means we + could easily move it into its own package at some later date. +</step> + +<step title="The Prefix type" src="doc/codewalk/markov.go:/type Prefix/"> + Since we'll be working with prefixes often, we define a + <code>Prefix</code> type with the concrete type <code>[]string</code>. + Defining a named type clearly allows us to be explicit when we are + working with a prefix instead of just a <code>[]string</code>. + Also, in Go we can define methods on any named type (not just structs), + so we can add methods that operate on <code>Prefix</code> if we need to. +</step> + +<step title="The String method" src="doc/codewalk/markov.go:/func[^\n]+String/,/}/"> + The first method we define on <code>Prefix</code> is + <code>String</code>. It returns a <code>string</code> representation + of a <code>Prefix</code> by joining the slice elements together with + spaces. We will use this method to generate keys when working with + the chain map. +</step> + +<step title="Building the chain" src="doc/codewalk/markov.go:/func[^\n]+Build/,/\n}/"> + The <code>Build</code> method reads text from an <code>io.Reader</code> + and parses it into prefixes and suffixes that are stored in the + <code>Chain</code>. + <br/><br/> + The <code><a href="/pkg/io/#Reader">io.Reader</a></code> is an + interface type that is widely used by the standard library and + other Go code. Our code uses the + <code><a href="/pkg/fmt/#Fscan">fmt.Fscan</a></code> function, which + reads space-separated values from an <code>io.Reader</code>. + <br/><br/> + The <code>Build</code> method returns once the <code>Reader</code>'s + <code>Read</code> method returns <code>os.EOF</code> (end of file) + or some other read error occurs. +</step> + +<step title="Buffering the input" src="doc/codewalk/markov.go:/bufio\.NewReader/"> + This function does many small reads, which can be inefficient for some + <code>Readers</code>. For efficiency we wrap the provided + <code>io.Reader</code> with + <code><a href="/pkg/bufio/">bufio.NewReader</a></code> to create a + new <code>io.Reader</code> that provides buffering. +</step> + +<step title="The Prefix variable" src="doc/codewalk/markov.go:/make\(Prefix/"> + At the top of the function we make a <code>Prefix</code> slice + <code>p</code> using the <code>Chain</code>'s <code>prefixLen</code> + field as its length. + We'll use this variable to hold the current prefix and mutate it with + each new word we encounter. +</step> + +<step title="Scanning words" src="doc/codewalk/markov.go:/var s string/,/\n }/"> + In our loop we read words from the <code>Reader</code> into a + <code>string</code> variable <code>s</code> using + <code>fmt.Fscan</code>. Since <code>Fscan</code> uses space to + separate each input value, each call will yield just one word + (including punctuation), which is exactly what we need. + <br/><br/> + <code>Fscan</code> returns an error if it encounters a read error + (<code>os.EOF</code>, for example) or if it can't scan the requested + value (in our case, a single string). In either case we just want to + stop scanning, so we <code>break</code> out of the loop. +</step> + +<step title="Adding a prefix and suffix to the chain" src="doc/codewalk/markov.go:/ key/,/key\], s\)"> + The word stored in <code>s</code> is a new suffix. We add the new + prefix/suffix combination to the <code>chain</code> map by computing + the map key with <code>p.String</code> and appending the suffix + to the slice stored under that key. + <br/><br/> + The built-in <code>append</code> function appends elements to a slice + and allocates new storage when necessary. When the provided slice is + <code>nil</code>, <code>append</code> allocates a new slice. + This behavior conveniently ties in with the semantics of our map: + retrieving an unset key returns the zero value of the value type and + the zero value of <code>[]string</code> is <code>nil</code>. + When our program encounters a new prefix (yielding a <code>nil</code> + value in the map) <code>append</code> will allocate a new slice. + <br/><br/> + For more information about the <code>append</code> function and slices + in general see the + <a href="http://blog.golang.org/2011/01/go-slices-usage-and-internals.html">Slices: usage and internals</a> article. +</step> + +<step title="Pushing the suffix onto the prefix" src="doc/codewalk/markov.go:/p\.Shift/"> + Before reading the next word our algorithm requires us to drop the + first word from the prefix and push the current suffix onto the prefix. + <br/><br/> + When in this state + <pre> +p == Prefix{"I", "am"} +s == "not" </pre> + the new value for <code>p</code> would be + <pre> +p == Prefix{"am", "not"}</pre> + This operation is also required during text generation so we put + the code to perform this mutation of the slice inside a method on + <code>Prefix</code> named <code>Shift</code>. +</step> + +<step title="The Shift method" src="doc/codewalk/markov.go:/func[^\n]+Shift/,/\n}/"> + The <code>Shift</code> method uses the built-in <code>copy</code> + function to copy the last len(p)-1 elements of <code>p</code> to + the start of the slice, effectively moving the elements + one index to the left (if you consider zero as the leftmost index). + <pre> +p := Prefix{"I", "am"} +copy(p, p[:1]) +// p == Prefix{"am", "am"}</pre> + We then assign the provided <code>word</code> to the last index + of the slice: + <pre> +// suffix == "not" +p[len(p)-1] = suffix +// p == Prefix{"am", "not"}</pre> +</step> + +<step title="Generating text" src="doc/codewalk/markov.go:/func[^\n]+Generate/,/\n}/"> + The <code>Generate</code> method is similar to <code>Build</code> + except that instead of reading words from a <code>Reader</code> + and storing them in a map, it reads words from the map and + appends them to a slice (<code>words</code>). + <br/><br/> + <code>Generate</code> uses a conditional for loop to generate + up to <code>n</code> words. +</step> + +<step title="Getting potential suffixes" src="doc/codewalk/markov.go:/choices/,/}\n/"> + At each iteration of the loop we retrieve a list of potential suffixes + for the current prefix. We access the <code>chain</code> map at key + <code>p.String()</code> and assign its contents to <code>choices</code>. + <br/><br/> + If <code>len(choices)</code> is zero we break out of the loop as there + are no potential suffixes for that prefix. + This test also works if the key isn't present in the map at all: + in that case, <code>choices</code> will be <code>nil</code> and the + length of a <code>nil</code> slice is zero. +</step> + +<step title="Choosing a suffix at random" src="doc/codewalk/markov.go:/next := choices/,/Shift/"> + To choose a suffix we use the + <code><a href="/pkg/rand/#Intn">rand.Intn</a></code> function. + It returns a random integer up to (but not including) the provided + value. Passing in <code>len(choices)</code> gives us a random index + into the full length of the list. + <br/><br/> + We use that index to pick our new suffix, assign it to + <code>next</code> and append it to the <code>words</code> slice. + <br/><br/> + Next, we <code>Shift</code> the new suffix onto the prefix just as + we did in the <code>Build</code> method. +</step> + +<step title="Returning the generated text" src="doc/codewalk/markov.go:/Join\(words/"> + Before returning the generated text as a string, we use the + <code>strings.Join</code> function to join the elements of + the <code>words</code> slice together, separated by spaces. +</step> + +<step title="Command-line flags" src="doc/codewalk/markov.go:/Register command-line flags/,/prefixLen/"> + To make it easy to tweak the prefix and generated text lengths we + use the <code><a href="/pkg/flag/">flag</a></code> package to parse + command-line flags. + <br/><br/> + These calls to <code>flag.Int</code> register new flags with the + <code>flag</code> package. The arguments to <code>Int</code> are the + flag name, its default value, and a description. The <code>Int</code> + function returns a pointer to an integer that will contain the + user-supplied value (or the default value if the flag was omitted on + the command-line). +</step> + +<step title="Program set up" src="doc/codewalk/markov.go:/flag.Parse/,/rand.Seed/"> + The <code>main</code> function begins by parsing the command-line + flags with <code>flag.Parse</code> and seeding the <code>rand</code> + package's random number generator with the current time. + <br/><br/> + If the command-line flags provided by the user are invalid the + <code>flag.Parse</code> function will print an informative usage + message and terminate the program. +</step> + +<step title="Creating and building a new Chain" src="doc/codewalk/markov.go:/c := NewChain/,/c\.Build/"> + To create the new <code>Chain</code> we call <code>NewChain</code> + with the value of the <code>prefix</code> flag. + <br/><br/> + To build the chain we call <code>Build</code> with + <code>os.Stdin</code> (which implements <code>io.Reader</code>) so + that it will read its input from standard input. +</step> + +<step title="Generating and printing text" src="doc/codewalk/markov.go:/c\.Generate/,/fmt.Println/"> + Finally, to generate text we call <code>Generate</code> with + the value of the <code>words</code> flag and assigning the result + to the variable <code>text</code>. + <br/><br/> + Then we call <code>fmt.Println</code> to write the text to standard + output, followed by a carriage return. +</step> + +<step title="Using this program" src="doc/codewalk/markov.go"> + To use this program, first compile and link it. + If you are using <code>6g</code> as your compiler, the command + would look something like this: + <pre> +$ 6g markov.go && 6l -o markov markov.6</pre> + And then execute it while piping in some input text: + <pre> +$ echo "a man a plan a canal panama" | ./markov -prefix=1 +a plan a man a plan a canal panama + </pre> + Here's a transcript of generating some text using the Go distribution's + README file as source material: + <pre> +$ ./markov -words=10 < $GOROOT/go/README +This is the source code repository for the Go source +$ ./markov -prefix=1 -words=10 < $GOROOT/go/README +This is the go directory (the one containing this README). +$ ./markov -prefix=1 -words=10 < $GOROOT/go/README +This is the variable if you have just untarred a</pre> +</step> + +<step title="An exercise for the reader" src="doc/codewalk/markov.go"> + The <code>Generate</code> function does a lot of allocations when it + builds the <code>words</code> slice. As an exercise, modify it to + take an <code>io.Writer</code> to which it incrementally writes the + generated text with <code>Fprint</code>. + Aside from being more efficient this makes <code>Generate</code> + more symmetrical to <code>Build</code>. +</step> + +</codewalk> diff --git a/doc/codewalk/pig.go b/doc/codewalk/pig.go new file mode 100644 index 000000000..9e415f589 --- /dev/null +++ b/doc/codewalk/pig.go @@ -0,0 +1,124 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "fmt" + "rand" +) + +const ( + win = 100 // The winning score in a game of Pig + gamesPerSeries = 10 // The number of games per series to simulate +) + +// A score includes scores accumulated in previous turns for each player, +// as well as the points scored by the current player in this turn. +type score struct { + player, opponent, thisTurn int +} + +// An action transitions stochastically to a resulting score. +type action func(current score) (result score, turnIsOver bool) + +// roll returns the (result, turnIsOver) outcome of simulating a die roll. +// If the roll value is 1, then thisTurn score is abandoned, and the players' +// roles swap. Otherwise, the roll value is added to thisTurn. +func roll(s score) (score, bool) { + outcome := rand.Intn(6) + 1 // A random int in [1, 6] + if outcome == 1 { + return score{s.opponent, s.player, 0}, true + } + return score{s.player, s.opponent, outcome + s.thisTurn}, false +} + +// stay returns the (result, turnIsOver) outcome of staying. +// thisTurn score is added to the player's score, and the players' roles swap. +func stay(s score) (score, bool) { + return score{s.opponent, s.player + s.thisTurn, 0}, true +} + +// A strategy chooses an action for any given score. +type strategy func(score) action + +// stayAtK returns a strategy that rolls until thisTurn is at least k, then stays. +func stayAtK(k int) strategy { + return func(s score) action { + if s.thisTurn >= k { + return stay + } + return roll + } +} + +// play simulates a Pig game and returns the winner (0 or 1). +func play(strategy0, strategy1 strategy) int { + strategies := []strategy{strategy0, strategy1} + var s score + var turnIsOver bool + currentPlayer := rand.Intn(2) // Randomly decide who plays first + for s.player+s.thisTurn < win { + action := strategies[currentPlayer](s) + if action != roll && action != stay { + panic(fmt.Sprintf("Player %d is cheating", currentPlayer)) + } + s, turnIsOver = action(s) + if turnIsOver { + currentPlayer = (currentPlayer + 1) % 2 + } + } + return currentPlayer +} + +// roundRobin simulates a series of games between every pair of strategies. +func roundRobin(strategies []strategy) ([]int, int) { + wins := make([]int, len(strategies)) + for i := 0; i < len(strategies); i++ { + for j := i + 1; j < len(strategies); j++ { + for k := 0; k < gamesPerSeries; k++ { + winner := play(strategies[i], strategies[j]) + if winner == 0 { + wins[i]++ + } else { + wins[j]++ + } + } + } + } + gamesPerStrategy := gamesPerSeries * (len(strategies) - 1) // no self play + return wins, gamesPerStrategy +} + +// ratioString takes a list of integer values and returns a string that lists +// each value and its percentage of the sum of all values. +// e.g., ratios(1, 2, 3) = "1/6 (16.7%), 2/6 (33.3%), 3/6 (50.0%)" +func ratioString(vals ...int) string { + total := 0 + for _, val := range vals { + total += val + } + s := "" + for _, val := range vals { + if s != "" { + s += ", " + } + pct := 100 * float64(val) / float64(total) + s += fmt.Sprintf("%d/%d (%0.1f%%)", val, total, pct) + } + return s +} + +func main() { + strategies := make([]strategy, win) + for k := range strategies { + strategies[k] = stayAtK(k + 1) + } + wins, games := roundRobin(strategies) + + for k := range strategies { + fmt.Printf("Wins, losses staying at k =% 4d: %s\n", + k+1, ratioString(wins[k], games-wins[k])) + } +} diff --git a/doc/codewalk/popout.png b/doc/codewalk/popout.png Binary files differnew file mode 100644 index 000000000..9c0c23638 --- /dev/null +++ b/doc/codewalk/popout.png diff --git a/doc/codewalk/sharemem.xml b/doc/codewalk/sharemem.xml new file mode 100644 index 000000000..1a669f7b5 --- /dev/null +++ b/doc/codewalk/sharemem.xml @@ -0,0 +1,181 @@ +<codewalk title="Share Memory By Communicating"> + +<step title="Introduction" src="doc/codewalk/urlpoll.go"> +Go's approach to concurrency differs from the traditional use of +threads and shared memory. Philosophically, it can be summarized: +<br/><br/> +<i>Don't communicate by sharing memory; share memory by communicating.</i> +<br/><br/> +Channels allow you to pass references to data structures between goroutines. +If you consider this as passing around ownership of the data (the ability to +read and write it), they become a powerful and expressive synchronization +mechanism. +<br/><br/> +In this codewalk we will look at a simple program that polls a list of +URLs, checking their HTTP response codes and periodically printing their state. +</step> + +<step title="State type" src="doc/codewalk/urlpoll.go:/State/,/}/"> +The State type represents the state of a URL. +<br/><br/> +The Pollers send State values to the StateMonitor, +which maintains a map of the current state of each URL. +</step> + +<step title="Resource type" src="doc/codewalk/urlpoll.go:/Resource/,/}/"> +A Resource represents the state of a URL to be polled: the URL itself +and the number of errors encountered since the last successful poll. +<br/><br/> +When the program starts, it allocates one Resource for each URL. +The main goroutine and the Poller goroutines send the Resources to +each other on channels. +</step> + +<step title="Poller function" src="doc/codewalk/urlpoll.go:/func Poller/,/\n}/"> +Each Poller receives Resource pointers from an input channel. +In this program, the convention is that sending a Resource pointer on +a channel passes ownership of the underlying data from the sender +to the receiver. Because of this convention, we know that +no two goroutines will access this Resource at the same time. +This means we don't have to worry about locking to prevent concurrent +access to these data structures. +<br/><br/> +The Poller processes the Resource by calling its Poll method. +<br/><br/> +It sends a State value to the status channel, to inform the StateMonitor +of the result of the Poll. +<br/><br/> +Finally, it sends the Resource pointer to the out channel. This can be +interpreted as the Poller saying "I'm done with this Resource" and +returning ownership of it to the main goroutine. +<br/><br/> +Several goroutines run Pollers, processing Resources in parallel. +</step> + +<step title="The Poll method" src="doc/codewalk/urlpoll.go:/Poll executes/,/\n}/"> +The Poll method (of the Resource type) performs an HTTP HEAD request +for the Resource's URL and returns the HTTP response's status code. +If an error occurs, Poll logs the message to standard error and returns the +error string instead. +</step> + +<step title="main function" src="doc/codewalk/urlpoll.go:/func main/,/\n}/"> +The main function starts the Poller and StateMonitor goroutines +and then loops passing completed Resources back to the pending +channel after appropriate delays. +</step> + +<step title="Creating channels" src="doc/codewalk/urlpoll.go:/create our/,/complete/"> +First, main makes two channels of *Resource, pending and complete. +<br/><br/> +Inside main, a new goroutine sends one Resource per URL to pending +and the main goroutine receives completed Resources from complete. +<br/><br/> +The pending and complete channels are passed to each of the Poller +goroutines, within which they are known as in and out. +</step> + +<step title="Initializing StateMonitor" src="doc/codewalk/urlpoll.go:/launch the StateMonitor/,/statusInterval/"> +StateMonitor will initialize and launch a goroutine that stores the state +of each Resource. We will look at this function in detail later. +<br/><br/> +For now, the important thing to note is that it returns a channel of State, +which is saved as status and passed to the Poller goroutines. +</step> + +<step title="Launching Poller goroutines" src="doc/codewalk/urlpoll.go:/launch some Poller/,/}/"> +Now that it has the necessary channels, main launches a number of +Poller goroutines, passing the channels as arguments. +The channels provide the means of communication between the main, Poller, and +StateMonitor goroutines. +</step> + +<step title="Send Resources to pending" src="doc/codewalk/urlpoll.go:/send some Resources/,/}\(\)/"> +To add the initial work to the system, main starts a new goroutine +that allocates and sends one Resource per URL to pending. +<br/><br/> +The new goroutine is necessary because unbuffered channel sends and +receives are synchronous. That means these channel sends will block until +the Pollers are ready to read from pending. +<br/><br/> +Were these sends performed in the main goroutine with fewer Pollers than +channel sends, the program would reach a deadlock situation, because +main would not yet be receiving from complete. +<br/><br/> +Exercise for the reader: modify this part of the program to read a list of +URLs from a file. (You may want to move this goroutine into its own +named function.) +</step> + +<step title="Main Event Loop" src="doc/codewalk/urlpoll.go:/range complete/,/\n }/"> +When a Poller is done with a Resource, it sends it on the complete channel. +This loop receives those Resource pointers from complete. +For each received Resource, it starts a new goroutine calling +the Resource's Sleep method. Using a new goroutine for each +ensures that the sleeps can happen in parallel. +<br/><br/> +Note that any single Resource pointer may only be sent on either pending or +complete at any one time. This ensures that a Resource is either being +handled by a Poller goroutine or sleeping, but never both simultaneously. +In this way, we share our Resource data by communicating. +</step> + +<step title="The Sleep method" src="doc/codewalk/urlpoll.go:/Sleep/,/\n}/"> +Sleep calls time.Sleep to pause before sending the Resource to done. +The pause will either be of a fixed length (pollInterval) plus an +additional delay proportional to the number of sequential errors (r.errCount). +<br/><br/> +This is an example of a typical Go idiom: a function intended to run inside +a goroutine takes a channel, upon which it sends its return value +(or other indication of completed state). +</step> + +<step title="StateMonitor" src="doc/codewalk/urlpoll.go:/StateMonitor/,/\n}/"> +The StateMonitor receives State values on a channel and periodically +outputs the state of all Resources being polled by the program. +</step> + +<step title="The updates channel" src="doc/codewalk/urlpoll.go:/updates :=/"> +The variable updates is a channel of State, on which the Poller goroutines +send State values. +<br/><br/> +This channel is returned by the function. +</step> + +<step title="The urlStatus map" src="doc/codewalk/urlpoll.go:/urlStatus/"> +The variable urlStatus is a map of URLs to their most recent status. +</step> + +<step title="The Ticker object" src="doc/codewalk/urlpoll.go:/ticker/"> +A time.Ticker is an object that repeatedly sends a value on a channel at a +specified interval. +<br/><br/> +In this case, ticker triggers the printing of the current state to +standard output every updateInterval nanoseconds. +</step> + +<step title="The StateMonitor goroutine" src="doc/codewalk/urlpoll.go:/go func/,/}\(\)/"> +StateMonitor will loop forever, selecting on two channels: +ticker.C and update. The select statement blocks until one of its +communications is ready to proceed. +<br/><br/> +When StateMonitor receives a tick from ticker.C, it calls logState to +print the current state. When it receives a State update from updates, +it records the new status in the urlStatus map. +<br/><br/> +Notice that this goroutine owns the urlStatus data structure, +ensuring that it can only be accessed sequentially. +This prevents memory corruption issues that might arise from parallel reads +and/or writes to a shared map. +</step> + +<step title="Conclusion" src="doc/codewalk/urlpoll.go"> +In this codewalk we have explored a simple example of using Go's concurrency +primitives to share memory through commmunication. +<br/><br/> +This should provide a starting point from which to explore the ways in which +goroutines and channels can be used to write expressive and concise concurrent +programs. +</step> + +</codewalk> diff --git a/doc/codewalk/urlpoll.go b/doc/codewalk/urlpoll.go new file mode 100644 index 000000000..b51be9502 --- /dev/null +++ b/doc/codewalk/urlpoll.go @@ -0,0 +1,117 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "http" + "log" + "time" +) + +const ( + numPollers = 2 // number of Poller goroutines to launch + second = 1e9 // one second is 1e9 nanoseconds + pollInterval = 60 * second // how often to poll each URL + statusInterval = 10 * second // how often to log status to stdout + errTimeout = 10 * second // back-off timeout on error +) + +var urls = []string{ + "http://www.google.com/", + "http://golang.org/", + "http://blog.golang.org/", +} + +// State represents the last-known state of a URL. +type State struct { + url string + status string +} + +// StateMonitor maintains a map that stores the state of the URLs being +// polled, and prints the current state every updateInterval nanoseconds. +// It returns a chan State to which resource state should be sent. +func StateMonitor(updateInterval int64) chan<- State { + updates := make(chan State) + urlStatus := make(map[string]string) + ticker := time.NewTicker(updateInterval) + go func() { + for { + select { + case <-ticker.C: + logState(urlStatus) + case s := <-updates: + urlStatus[s.url] = s.status + } + } + }() + return updates +} + +// logState prints a state map. +func logState(s map[string]string) { + log.Println("Current state:") + for k, v := range s { + log.Printf(" %s %s", k, v) + } +} + +// Resource represents an HTTP URL to be polled by this program. +type Resource struct { + url string + errCount int64 +} + +// Poll executes an HTTP HEAD request for url +// and returns the HTTP status string or an error string. +func (r *Resource) Poll() string { + resp, err := http.Head(r.url) + if err != nil { + log.Println("Error", r.url, err) + r.errCount++ + return err.String() + } + r.errCount = 0 + return resp.Status +} + +// Sleep sleeps for an appropriate interval (dependant on error state) +// before sending the Resource to done. +func (r *Resource) Sleep(done chan *Resource) { + time.Sleep(pollInterval + errTimeout*r.errCount) + done <- r +} + +func Poller(in <-chan *Resource, out chan<- *Resource, status chan<- State) { + for r := range in { + s := r.Poll() + status <- State{r.url, s} + out <- r + } +} + +func main() { + // create our input and output channels + pending, complete := make(chan *Resource), make(chan *Resource) + + // launch the StateMonitor + status := StateMonitor(statusInterval) + + // launch some Poller goroutines + for i := 0; i < numPollers; i++ { + go Poller(pending, complete, status) + } + + // send some Resources to the pending queue + go func() { + for _, url := range urls { + pending <- &Resource{url: url} + } + }() + + for r := range complete { + go r.Sleep(pending) + } +} diff --git a/doc/community.html b/doc/community.html new file mode 100644 index 000000000..c3b16cacb --- /dev/null +++ b/doc/community.html @@ -0,0 +1,53 @@ +<!-- title Community --> + +<div class="left-column"> + +<h2 id="developer_info">The Go Community</h2> + +<h3 id="mailinglist"><a href="http://groups.google.com/group/golang-nuts">Go Nuts Mailing List</a></h3> +<p>The <a href="http://groups.google.com/group/golang-nuts">golang-nuts</a> +mailing list is for general Go discussion.</p> + +<h3 id=""><a href="http://godashboard.appspot.com/package">Go Packages Dashboard</a></h3> +<p>A list of the most popular <a href="/cmd/goinstall/">goinstall</a>'d +Go libraries.</p> + +<h3 id=""><a href="http://godashboard.appspot.com/project">Go Project Dashboard</a></h3> +<p>A list of external Go projects including programs and libraries.</p> + +<h3 id="irc"><a href="irc:irc.freenode.net/go-nuts">Go IRC Channel</a></h3> +<p><b>#go-nuts</b> on <b>irc.freenode.net</b> is the official Go IRC channel.</p> + +<h3 id="twitter"><a href="http://twitter.com/go_nuts">@go_nuts at Twitter</a></h3> +<p>The Go project's official Twitter account.</p> + +</div> + +<div class="right-column"> + +<h2 id="blogs">Blogs</h2> + +<h3 id="blog_go"><a href="http://blog.golang.org/">The Go Blog</a></h3> +<p> +The Go project's official blog, maintained by the core Go developers. +</p> + +<h3 id="blog_rsc"><a href="http://research.swtch.com/search/label/Go">research!rsc</a></h3> +<p> +Posts labelled 'Go' by Russ Cox, one of the core Go developers. +</p> + +<h3 id="blog_iant"><a href="http://www.airs.com/blog/archives/category/programming">Airs</a></h3> +<p> +Posts labelled 'Programming' by Ian Lance Taylor, one of the core Go developers. +</p> + +<h3 id="blog_adg"><a href="http://nf.id.au/tag/go">nf.id.au</a></h3> +<p> +Posts labelled 'Go' by Andrew Gerrand, one of the core Go developers. +</p> + +</div> + +<div class="end-columns"></div> + diff --git a/doc/contrib.html b/doc/contrib.html new file mode 100644 index 000000000..84d2cda6a --- /dev/null +++ b/doc/contrib.html @@ -0,0 +1,69 @@ +<!-- title Contributing --> + +<div class="left-column"> + +<h2 id="howto">How you can help</h2> + +<h3><a href="http://code.google.com/p/go/issues">Reporting issues</a></h3> + +<p> +If you spot bugs, mistakes, or inconsistencies in the Go project's code or +documentation, please let us know by +<a href="http://code.google.com/p/go/issues/entry">filing a ticket</a> +on our <a href="http://code.google.com/p/go/issues">issue tracker</a>. +(Of course, you should check it's not an existing issue before creating +a new one.) +</p> + +<p> +We pride ourselves on being meticulous; no issue is too small. +</p> + +<h3><a href="contribute.html">Contributing code</a></h3> + +<p> +Go is an open source project and we welcome contributions from the community. +</p> +<p> +To get started, read these <a href="contribute.html">contribution +guidelines</a> for information on design, testing, and our code review process. +</p> +<p> +Check <a href="http://code.google.com/p/go/issues">the tracker</a> for +open issues that interest you. Those labeled +<a href="http://code.google.com/p/go/issues/list?q=status=HelpWanted">HelpWanted</a> +are particularly in need of outside help. +</p> + +</div> + +<div class="right-column"> + +<h2 id="the_go_project">The Go Project</h2> + +<h3 id="build_status"><a href="http://godashboard.appspot.com/">Build Status</a></h3> +<p>View the status of Go builds across the supported operating +systems and architectures.</p> + +<h3 id="roadmap"><a href="devel/roadmap.html">Roadmap</a></h3> +<p>Features and ideas being developed or discussed by the Go team.</p> + +<h3 id="release"><a href="devel/release.html">Release History</a></h3> +<p>A summary of the changes between Go releases.</p> + +<h3 id="release"><a href="devel/weekly.html">Weekly Snapshot History</a></h3> +<p>A summary of the changes between weekly snapshots of Go.</p> + +<h3 id="golang-dev"><a href="http://groups.google.com/group/golang-dev">Developer Mailing List</a></h3> +<p>The <a href="http://groups.google.com/group/golang-dev">golang-dev</a> +mailing list is for discussing and reviewing code for the Go project.</p> +<p>For general discussion of Go programming, see <a +href="http://groups.google.com/group/golang-nuts">golang-nuts</a>.</p> + +<h3 id="golang-checkins"><a href="http://groups.google.com/group/golang-checkins">Checkins Mailing List</a></h3> +<p>A mailing list that receives a message summarizing each checkin to the Go repository.</p> + +</div> + +<div class="end-columns"></div> + diff --git a/doc/contribute.html b/doc/contribute.html new file mode 100644 index 000000000..c4b1ce2b5 --- /dev/null +++ b/doc/contribute.html @@ -0,0 +1,529 @@ +<!-- Contribution Guidelines --> + +<h2 id="Introduction">Introduction</h2> + +<p> +This document explains how to contribute changes to the Go project. +It assumes you have installed Go using the +<a href="install.html">installation instructions</a> and +have <a href="code.html">written and tested your code</a>. +(Note that the <code>gccgo</code> frontend lives elsewhere; +see <a href="gccgo_contribute.html">Contributing to gccgo</a>.) +</p> + +<h2 id="Design">Discuss your design</h2> + +<p> +The project welcomes submissions but please let everyone know what +you're working on if you want it to become part of the main repository. +</p> + +<p> +Before undertaking to write something new for the Go project, send +mail to the <a href="http://groups.google.com/group/golang-nuts">mailing +list</a> to discuss what you plan to do. This gives everyone a +chance to validate the design, helps prevent duplication of effort, +and ensures that the idea fits inside the goals for the language +and tools. It also guarantees that the design is sound before code +is written; the code review tool is not the place for high-level +discussions. +</p> + +<p> +In short, send mail before you code. +And don't start the discussion by mailing a change list! +</p> + +<h2 id="Testing">Testing redux</h2> + +<p> +You've <a href="code.html">written and tested your code</a>, but +before sending code out for review, run all the tests for the whole +tree to make sure the changes don't break other packages or programs: +</p> + +<pre> +cd $GOROOT/src +./all.bash +</pre> + +<p> +The final line printed by <code>make all</code> should be of the form: +</p> + +<pre> +<i>N</i> known bugs; 0 unexpected bugs +</pre> + +<p> +The value of <i>N</i> varies over time, but the line must +say “<code>0 unexpected bugs</code>” and must not +add “<code>test output differs</code>.” +</p> + + +<h2 id="Code_review">Code review</h2> + +<p> +Changes to Go must be reviewed before they are submitted, +no matter who makes the change. +(In exceptional cases, such as fixing a build, the review can +follow shortly after submitting.) +A Mercurial extension helps manage the code review process. +The extension is included in the Go source tree but needs +to be added to your Mercurial configuration. +</p> + +<h3>Caveat for Mercurial aficionados</h3> + +<p> +<i>Using Mercurial with the code review extension is not the same +as using standard Mercurial.</i> +</p> + +<p> +The Go repository is maintained as a single line of reviewed changes; +we prefer to avoid the complexity of Mercurial's arbitrary change graph. +The code review extension helps here: its <code>hg submit</code> command +automatically checks for and warns about the local repository +being out of date compared to the remote one. +The <code>hg submit</code> command also verifies other +properties about the Go repository. +For example, +it checks that Go code being checked in is formatted in the standard style, +as defined by <a href="/cmd/gofmt">gofmt</a>, +and it checks that the author of the code is properly recorded for +<a href="#copyright">copyright purposes</a>. +</p> + +<p> +To help ensure changes are only created by <code>hg submit</code>, +the code review extension disables the standard <code>hg commit</code> +command. +</p> + +<p> +Mercurial power users: if you prefer to use the Mercurial Queues extension, see +<a href="codereview_with_mq.html">Using Mercurial Queues with Codereview</a>. +</p> + +<h3>Configure the extension</h3> + +<p>Edit <code>$GOROOT/.hg/hgrc</code> to add:</p> + +<pre> +[extensions] +codereview = YOUR_GO_ROOT/lib/codereview/codereview.py + +[ui] +username = Your Name <you@server.dom> +</pre> + +<p>Replace YOUR_GO_ROOT with the value of <code>$GOROOT</code>. +The Mercurial configuration file format does not allow environment variable substitution. +The <code>username</code> information will not be used unless +you are a committer (see below), but Mercurial complains if it is missing. +</p> + +<h3>Log in to the code review site.</h3> + +<p> +The code review server uses a Google Account to authenticate. +(If you can use the account to +<a href="https://www.google.com/accounts/Login?hl=en&continue=http://www.google.com/">sign in at google.com</a>, +you can use it to sign in to the code review server. +The email address you use on the Code Review site +will be recorded in the <a href="http://code.google.com/p/go/source/list">Mercurial change log</a> +and in the <a href="/CONTRIBUTORS"><code>CONTRIBUTORS</code></a> file. +You can <a href="https://www.google.com/accounts/NewAccount">create a Google Account</a> +associated with any address where you receive email. +</p> + +<pre> +$ cd $GOROOT +$ hg code-login +Email (login for uploading to codereview.appspot.com): rsc@golang.org +Password for rsc@golang.org: + +Saving authentication cookies to /Users/rsc/.codereview_upload_cookies_codereview.appspot.com +</pre> + +<h3>Configure your account settings.</h3> + +<p>Edit your <a href="http://codereview.appspot.com/settings">code review settings</a>. +Grab a nickname. +Many people prefer to set the Context option to +“Whole file” to see more context when reviewing changes. +</p> + +<p>Once you have chosen a nickname in the settings page, others +can use that nickname as a shorthand for naming reviewers and the CC list. +For example, <code>rsc</code> is an alias for <code>rsc@golang.org</code>. +</p> + +<h3>Make a change</h3> + +<p> +The entire checked-out tree is writable. +If you need to edit files, just edit them: Mercurial will figure out which ones changed. +You do need to inform Mercurial of added, removed, copied, or renamed files, +by running +<code>hg add</code>, +<code>hg rm</code>, +<code>hg cp</code>, +or +<code>hg mv</code>. +</p> + +<p>When you are ready to send a change out for review, run</p> + +<pre> +$ hg change +</pre> + +<p>from any directory in your Go repository. +Mercurial will open a change description file in your editor. +(It uses the editor named by the <code>$EDITOR</code> environment variable, <code>vi</code> by default.) +The file will look like: +</p> + +<pre> +# Change list. +# Lines beginning with # are ignored. +# Multi-line values should be indented. + +Reviewer: +CC: + +Description: + <enter description here> + +Files: + src/pkg/math/sin.go + src/pkg/math/tan.go + src/pkg/regexp/regexp.go +</pre> + +<p> +The <code>Reviewer</code> line lists the reviewers assigned +to this change, and the <code>CC</code> line lists people to +notify about the change. +These can be code review nicknames or arbitrary email addresses. +Unless explicitly told otherwise, such as in the discussion leading +up to sending in the change list, set the +reviewer field to the +<a href="http://groups.google.com/group/golang-dev">golang-dev@googlegroups.com</a> +mailing list. +</p> + +<p> +Replace “<code><enter description here></code>” +with a description of your change. +The first line of the change description is conventionally a one-line +summary of the change, prefixed by the primary affected package, +and is used as the subject for code review mail; the rest of the +description elaborates. +</p> + +<p> +The <code>Files</code> section lists all the modified files +in your client. +It is best to keep unrelated changes in different change lists. +In this example, we can include just the changes to package <code>math</code> +by deleting the line mentioning <code>regexp.go</code>. +</p> + +<p> +After editing, the template might now read: +</p> + +<pre> +# Change list. +# Lines beginning with # are ignored. +# Multi-line values should be indented. + +Reviewer: golang-dev@googlegroups.com +CC: math-nuts@swtch.com + +Description: + math: improved Sin, Cos and Tan precision for very large arguments. + + See Bimmler and Shaney, ``Extreme sinusoids,'' J. Math 3(14). + Fixes issue 159. + +Files: + src/pkg/math/sin.go + src/pkg/math/tan.go +</pre> + +<p> +The special sentence “Fixes issue 159.” associates +the change with issue 159 in the <a href="http://code.google.com/p/go/issues/list">Go issue tracker</a>. +When this change is eventually submitted, the issue +tracker will automatically mark the issue as fixed. +</p> + +<p> +Save the file and exit the editor.</p> + +<p> +The code review server assigns your change an issue number and URL, +which <code>hg change</code> will print, something like: +</p> + +<pre> +CL created: http://codereview.appspot.com/99999 +</pre> + +<p> +If you need to re-edit the change description, +run <code>hg change 99999</code>. +</p> + +<p> +You can see a list of your pending changes by running <code>hg pending</code> (<code>hg p</code> for short). +</p> + + +<h3>Synchronize your client</h3> + +<p>While you were working, others might have submitted changes +to the repository. To update your client, run</p> + +<pre> +$ hg sync +</pre> + +<p>(For Mercurial fans, <code>hg sync</code> runs <code>hg pull -u</code> +but then also synchronizes the local change list state against the new data.)</p> + +<p> +If files you were editing have changed, Mercurial does its best to merge the +remote changes into your local changes. It may leave some files to merge by hand. +</p> + +<p> +For example, suppose you have edited <code>flag_test.go</code> but +someone else has committed an independent change. +When you run <code>hg sync</code>, you will get the (scary-looking) output +(emphasis added): + +<pre> +$ hg sync +adding changesets +adding manifests +adding file changes +added 1 changeset with 2 changes to 2 files +getting src/pkg/flag/flag.go +couldn't find merge tool hgmerge +merging src/pkg/flag/flag_test.go +warning: conflicts during merge. +<i>merging src/pkg/flag/flag_test.go failed!</i> +1 file updated, 0 files merged, 0 files removed, 1 file unresolved +use 'hg resolve' to retry unresolved file merges +$ +</pre> + +<p> +The only important part in that transcript is the italicized line: +Mercurial failed to merge your changes with the independent change. +When this happens, Mercurial leaves both edits in the file, +marked by <code><<<<<<<</code> and +<code>>>>>>>></code>. +it is now your job to edit the file to combine them. +Continuing the example, searching for those strings in <code>flag_test.go</code> +might turn up: +</p> + +<pre> + VisitAll(visitor); +<<<<<<< local + if len(m) != 7 { +======= + if len(m) != 8 { +>>>>>>> other + t.Error("VisitAll misses some flags"); +</pre> + +<p> +Mercurial doesn't show it, but suppose the original text that both edits +started with was 6; you added 1 and the other change added 2, +so the correct answer might now be 9. First, edit the section +to remove the markers and leave the correct code: +</p> + +<pre> + VisitAll(visitor); + if len(m) != 9 { + t.Error("VisitAll misses some flags"); +</pre> + +<p> +Then ask Mercurial to mark the conflict as resolved: +</p> + +<pre> +$ hg resolve -m flag_test.go +</pre> + +<p> +If you had been editing the file, say for debugging, but do not +care to preserve your changes, you can run +<code>hg revert flag_test.go</code> to abandon your +changes, but you may still need to run +<code>hg resolve -m</code> to mark the conflict resolved. +</p> + +<h3>Mail the change for review</h3> + +<p>To send out a change for review, run <code>hg mail</code> using the change list number +assigned during <code>hg change</code>:</p> + +<pre> +$ hg mail 99999 +</pre> + +<p>You can add to the <code>Reviewer:</code> and <code>CC:</code> lines +using the <code>-r</code> or <code>--cc</code> options. +In the above example, we could have left the <code>Reviewer</code> and <code>CC</code> +lines blank and then run: +</p> + +<pre> +$ hg mail -r golang-dev@googlegroups.com --cc math-nuts@swtch.com 99999 +</pre> + +<p>to achieve the same effect.</p> + +<p>Note that <code>-r</code> and <code>--cc</code> cannot be spelled <code>--r</code> or <code>-cc</code>.</p> + + +<h3>Reviewing code</h3> + +<p> +Running <code>hg mail</code> will send an email to you and the reviewers +asking them to visit the issue's URL and make coments on the change. +When done, the reviewer clicks “Publish and Mail comments” +to send comments back. +</p> + + +<h3>Revise and upload</h3> + +<p>You will probably revise your code in response to the reviewer comments. +When you have revised the code and are ready for another round of review, run +</p> + +<pre> +$ hg mail 99999 +</pre> + +<p>again to upload the latest copy and send mail asking the reviewers to please take another look +(<code>PTAL</code>). +You might also visit the code review web page and reply to the comments, +letting the reviewer know that you've addressed them or explain why you +haven't. When you're done replying, click “Publish and Mail comments” +to send the line-by-line replies and any other comments. +</p> +<p> +The reviewer can comment on the new copy, and the process repeats. +The reviewer approves the change by replying with a mail that says +<code>LGTM</code>: looks good to me. +</p> + +<h3>Submit the change after the review</h3> + +<p> +After the code has been <code>LGTM</code>'ed, it is time to submit +it to the Mercurial repository. +If you are a committer, you can run: +</p> + +<pre> +$ hg submit 99999 +</pre> + +<p> +This checks the change into the repository. +The change description will include a link to the code review, +and the code review will be updated with a link to the change +in the repository. +</p> + +<p> +If your local copy of the repository is out of date, +<code>hg submit</code> +will refuse the change: +</p> + +<pre> +$ hg submit 99999 +local repository out of date; must sync before submit +</pre> + +<p> +If you are not a committer, you cannot submit the change directly. +Instead, a committer, usually the reviewer who said <code>LGTM</code>, +will run: +</p> + +<pre> +$ hg clpatch 99999 +$ hg submit 99999 +</pre> + +<p>The <code>clpatch</code> command imports your change 99999 into +the committer's local Mercurial client, at which point the committer +can check or test the code more. +(Anyone can run <code>clpatch</code> to try a change that +has been uploaded to the code review server.) +The <code>submit</code> command submits the code. You will be listed as the +author, but the change message will also indicate who the committer was. +Your local client will notice that the change has been submitted +when you next run <code>hg sync</code>. +</p> + + +<h3 id="copyright">Copyright</h3> + +<p>Files in the Go repository don't list author names, +both to avoid clutter and to avoid having to keep the lists up to date. +Instead, your name will appear in the <a href="http://code.google.com/p/go/source/list">Mercurial change log</a> +and in the <a href="/CONTRIBUTORS"><code>CONTRIBUTORS</code></a> file +and perhaps the <a href="/AUTHORS"><code>AUTHORS</code></a> file. +</p> + +<p>The <a href="/CONTRIBUTORS"><code>CONTRIBUTORS</code></a> file +defines who the Go contributors—the people—are; +the <a href="/AUTHORS"><code>AUTHORS</code></a> file, which defines +who “The Go Authors”—the copyright holders—are. +The Go developers at Google will update these files when submitting +your first change. +In order for them to do that, you need to have completed one of the +contributor license agreements: +<ul> +<li> +If you are the copyright holder, you will need to agree to +the <a href="http://code.google.com/legal/individual-cla-v1.0.html">individual +contributor license agreement</a>, which can be completed online. +</li> +<li> +If your organization is the copyright holder, the organization +will need to agree to the <a href="http://code.google.com/legal/corporate-cla-v1.0.html">corporate contributor license agreement</a>. +(If the copyright holder for your code has already completed the +agreement in connection with another Google open source project, +it does not need to be completed again.) +</li> +</ul> + +<p> +This rigmarole needs to be done only for your first submission. +</p> + +<p>Code that you contribute should use the standard copyright header:</p> + +<pre> +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +</pre> diff --git a/doc/devel/index.html b/doc/devel/index.html new file mode 100644 index 000000000..ae405bf52 --- /dev/null +++ b/doc/devel/index.html @@ -0,0 +1,11 @@ +<!-- The Go project --> + +<ul> +<li><a href="roadmap.html">Roadmap</a></li> +<li><a href="release.html">Release history</a></li> +<li><a href="weekly.html">Weekly snapshot history</a></li> +<li><a href="http://godashboard.appspot.com">Build and benchmark status</a></li> +</ul> +<ul> +<li><a href="../contribute.html">Contributing code</a></li> +</ul> diff --git a/doc/devel/release.html b/doc/devel/release.html new file mode 100644 index 000000000..458a116de --- /dev/null +++ b/doc/devel/release.html @@ -0,0 +1,436 @@ +<!-- Release History --> + +<p>This page summarizes the changes between official stable releases of Go. +Between releases we issue less stable +<a href="http://blog.golang.org/2011/03/go-becomes-more-stable.html">weekly snapshots</a>. +The <a href="weekly.html">weekly snapshot history</a> contains more detail, +and the <a href="http://code.google.com/p/go/source/list">Mercurial change log</a> +has full details.</p> + +<p>To update to a specific release, use:</p> + +<pre> +hg pull +hg update release.r<i>NN</i> +</pre> + +<h2 id="r60">r60 (released 2011/09/07)</h2> + +<p> +The r60 release corresponds to +<code><a href="weekly.html#2011-08-17">weekly.2011-08-17</a></code>. +This section highlights the most significant changes in this release. +For a more detailed summary, see the +<a href="weekly.html#2011-08-17">weekly release notes</a>. +For complete information, see the +<a href="http://code.google.com/p/go/source/list?r=release-branch.r60">Mercurial change list</a>. +</p> + +<h3 id="r60.lang">Language</h3> + +<p> +An "else" block is now required to have braces except if the body of the "else" +is another "if". Since gofmt always puts those braces in anyway, +gofmt-formatted programs will not be affected. +To fix other programs, run gofmt. +</p> + +<h3 id="r60.pkg">Packages</h3> + +<p> +<a href="/pkg/http/">Package http</a>'s URL parsing and query escaping code +(such as <code>ParseURL</code> and <code>URLEscape</code>) has been moved to +the new <a href="/pkg/url/">url package</a>, with several simplifications to +the names. Client code can be updated automatically with gofix. +</p> + +<p> +<a href="/pkg/image/">Package image</a> has had significant changes made to the +<code>Pix</code> field of struct types such as +<a href="/pkg/image/#RGBA">image.RGBA</a> and +<a href="/pkg/image/#NRGBA">image.NRGBA</a>. +The <a href="/pkg/image/#Image">image.Image</a> interface type has not changed, +though, and you should not need to change your code if you don't explicitly +refer to <code>Pix</code> fields. For example, if you decode a number of images +using the <a href="/pkg/image/jpeg/">image/jpeg</a> package, compose them using +<a href="/pkg/image/draw/">image/draw</a>, and then encode the result using +<a href="/pkg/img/png">image/png</a>, then your code should still work as +before. +If your code <i>does</i> refer to <code>Pix</code> fields see the +<a href="/doc/devel/weekly.html#2011-07-19">weekly.2011-07-19</a> +snapshot notes for how to update your code. +</p> + +<p> +<a href="/pkg/template/">Package template</a> has been replaced with a new +templating package (formerly <code>exp/template</code>). The original template +package is still available as <a href="/pkg/old/template/">old/template</a>. +The <code>old/template</code> package is deprecated and will be removed. +The Go tree has been updated to use the new template package. We encourage +users of the old template package to switch to the new one. Code that uses +<code>template</code> or <code>exp/template</code> will need to change its +import lines to <code>"old/template"</code> or <code>"template"</code>, +respectively. +</p> + +<h3 id="r60.cmd">Tools</h3> + +<p> +<a href="/cmd/goinstall/">Goinstall</a> now uses a new tag selection scheme. +When downloading or updating, goinstall looks for a tag or branch with the +<code>"go."</code> prefix that corresponds to the local Go version. For Go +<code>release.r58</code> it looks for <code>go.r58</code>. For +<code>weekly.2011-06-03</code> it looks for <code>go.weekly.2011-06-03</code>. +If the specific <code>go.X</code> tag or branch is not found, it chooses the +closest earlier version. If an appropriate tag or branch is found, goinstall +uses that version of the code. Otherwise it uses the default version selected +by the version control system. Library authors are encouraged to use the +appropriate tag or branch names in their repositories to make their libraries +more accessible. +</p> + +<h2 id="r59">r59 (released 2011/08/01)</h2> + +<p> +The r59 release corresponds to +<code><a href="weekly.html#2011-07-07">weekly.2011-07-07</a></code>. +This section highlights the most significant changes in this release. +For a more detailed summary, see the +<a href="weekly.html#2011-07-07">weekly release notes</a>. +For complete information, see the +<a href="http://code.google.com/p/go/source/list?r=release-branch.r59">Mercurial change list</a>. +</p> + +<h3 id="r59.lang">Language</h3> + +<p> +This release includes a language change that restricts the use of +<code>goto</code>. In essence, a <code>goto</code> statement outside a block +cannot jump to a label inside that block. Your code may require changes if it +uses <code>goto</code>. +See <a href="http://code.google.com/p/go/source/detail?r=dc6d3cf9279d">this +changeset</a> for how the new rule affected the Go tree. +</p> + +<h3 id="r59.pkg">Packages</h3> + +<p> +As usual, <a href="/cmd/gofix/">gofix</a> will handle the bulk of the rewrites +necessary for these changes to package APIs. +</p> + +<p> +<a href="/pkg/http">Package http</a> has a new +<a href="/pkg/http/#FileSystem">FileSystem</a> interface that provides access +to files. The <a href="/pkg/http/#FileServer">FileServer</a> helper now takes a +<code>FileSystem</code> argument instead of an explicit file system root. By +implementing your own <code>FileSystem</code> you can use the +<code>FileServer</code> to serve arbitrary data. +</p> + +<p> +<a href="/pkg/os/">Package os</a>'s <code>ErrorString</code> type has been +hidden. Most uses of <code>os.ErrorString</code> can be replaced with +<a href="/pkg/os/#NewError">os.NewError</a>. +</p> + +<p> +<a href="/pkg/reflect/">Package reflect</a> supports a new struct tag scheme +that enables sharing of struct tags between multiple packages. +In this scheme, the tags must be of the form: +</p> +<pre> + `key:"value" key2:"value2"` +</pre> +<p> +The <a href="/pkg/reflect/#StructField">StructField</a> type's Tag field now +has type <a href="/pkg/reflect/#StructTag">StructTag</a>, which has a +<code>Get</code> method. Clients of <a href="/pkg/json">json</a> and +<a href="/pkg/xml">xml</a> will need to be updated. Code that says +</p> +<pre> + type T struct { + X int "name" + } +</pre> +<p> +should become +</p> +<pre> + type T struct { + X int `json:"name"` // or `xml:"name"` + } +</pre> +<p> +Use <a href="/cmd/govet/">govet</a> to identify struct tags that need to be +changed to use the new syntax. +</p> + +<p> +<a href="/pkg/sort/">Package sort</a>'s <code>IntArray</code> type has been +renamed to <a href="/pkg/sort/#IntSlice">IntSlice</a>, and similarly for +<a href="/pkg/sort/#Float64Slice">Float64Slice</a> and +<a href="/pkg/sort/#StringSlice">StringSlice</a>. +</p> + +<p> +<a href="/pkg/strings/">Package strings</a>'s <code>Split</code> function has +itself been split into <a href="/pkg/strings/#Split">Split</a> and +<a href="/pkg/strings/#SplitN">SplitN</a>. +<code>SplitN</code> is the same as the old <code>Split</code>. +The new <code>Split</code> is equivalent to <code>SplitN</code> with a final +argument of -1. +</p> + +<a href="/pkg/image/draw/">Package image/draw</a>'s +<a href="/pkg/image/draw/#Draw">Draw</a> function now takes an additional +argument, a compositing operator. +If in doubt, use <a href="/pkg/image/draw/#Op">draw.Over</a>. +</p> + +<h3 id="r59.cmd">Tools</h3> + +<p> +<a href="/cmd/goinstall/">Goinstall</a> now installs packages and commands from +arbitrary remote repositories (not just Google Code, Github, and so on). +See the <a href="/cmd/goinstall/">goinstall documentation</a> for details. +</p> + +<h2 id="r58">r58 (released 2011/06/29)</h2> + +<p> +The r58 release corresponds to +<code><a href="weekly.html#2011-06-09">weekly.2011-06-09</a></code> +with additional bug fixes. +This section highlights the most significant changes in this release. +For a more detailed summary, see the +<a href="weekly.html#2011-06-09">weekly release notes</a>. +For complete information, see the +<a href="http://code.google.com/p/go/source/list?r=release-branch.r58">Mercurial change list</a>. +</p> + +<h3 id="r58.lang">Language</h3> + +<p> +This release fixes a <a href="http://code.google.com/p/go/source/detail?r=b720749486e1">use of uninitialized memory in programs that misuse <code>goto</code></a>. +</p> + +<h3 id="r58.pkg">Packages</h3> + +<p> +As usual, <a href="/cmd/gofix/">gofix</a> will handle the bulk of the rewrites +necessary for these changes to package APIs. +</p> + +<p> +<a href="/pkg/http/">Package http</a> drops the <code>finalURL</code> return +value from the <a href="/pkg/http/#Client.Get">Client.Get</a> method. The value +is now available via the new <code>Request</code> field on <a +href="/pkg/http/#Response">http.Response</a>. +Most instances of the type map[string][]string in have been +replaced with the new <a href="/pkg/http/#Values">Values</a> type. +</p> + +<p> +<a href="/pkg/exec/">Package exec</a> has been redesigned with a more +convenient and succinct API. +</p> + +<p> +<a href="/pkg/strconv/">Package strconv</a>'s <a href="/pkg/strconv/#Quote">Quote</a> +function now escapes only those Unicode code points not classified as printable +by <a href="/pkg/unicode/#IsPrint">unicode.IsPrint</a>. +Previously Quote would escape all non-ASCII characters. +This also affects the <a href="/pkg/fmt/">fmt</a> package's <code>"%q"</code> +formatting directive. The previous quoting behavior is still available via +strconv's new <a href="/pkg/strconv/#QuoteToASCII">QuoteToASCII</a> function. +</p> + +<p> +<a href="/pkg/os/signal/">Package os/signal</a>'s +<a href="/pkg/os/#Signal">Signal</a> and +<a href="/pkg/os/#UnixSignal">UnixSignal</a> types have been moved to the +<a href="/pkg/os/">os</a> package. +</p> + +<p> +<a href="/pkg/image/draw/">Package image/draw</a> is the new name for +<code>exp/draw</code>. The GUI-related code from <code>exp/draw</code> is now +located in the <a href="/pkg/exp/gui/">exp/gui</a> package. +</p> + +<h3 id="r58.cmd">Tools</h3> + +<p> +<a href="/cmd/goinstall/">Goinstall</a> now observes the GOPATH environment +variable to build and install your own code and external libraries outside of +the Go tree (and avoid writing Makefiles). +</p> + + +<h3 id="r58.minor">Minor revisions</h3> + +<p>r58.1 adds +<a href="http://code.google.com/p/go/source/detail?r=293c25943586">build</a> and +<a href="http://code.google.com/p/go/source/detail?r=bf17e96b6582">runtime</a> +changes to make Go run on OS X 10.7 Lion. +</p> + +<h2 id="r57">r57 (released 2011/05/03)</h2> + +<p> +The r57 release corresponds to +<code><a href="weekly.html#2011-04-27">weekly.2011-04-27</a></code> +with additional bug fixes. +This section highlights the most significant changes in this release. +For a more detailed summary, see the +<a href="weekly.html#2011-04-27">weekly release notes</a>. +For complete information, see the +<a href="http://code.google.com/p/go/source/list?r=release-branch.r57">Mercurial change list</a>. +</p> + +<p>The new <a href="/cmd/gofix">gofix</a> tool finds Go programs that use old APIs and rewrites them to use +newer ones. After you update to a new Go release, gofix helps make the +necessary changes to your programs. Gofix will handle the http, os, and syscall +package changes described below, and we will update the program to keep up with +future changes to the libraries. +Gofix can’t +handle all situations perfectly, so read and test the changes it makes before +committing them. +See <a href="http://blog.golang.org/2011/04/introducing-gofix.html">the gofix blog post</a> for more +information.</p> + +<h3 id="r57.lang">Language</h3> + +<p> +<a href="/doc/go_spec.html#Receive_operator">Multiple assignment syntax</a> replaces the <code>closed</code> function. +The syntax for channel +receives allows an optional second assigned value, a boolean value +indicating whether the channel is closed. This code: +</p> + +<pre> + v := <-ch + if closed(ch) { + // channel is closed + } +</pre> + +<p>should now be written as:</p> + +<pre> + v, ok := <-ch + if !ok { + // channel is closed + } +</pre> + +<p><a href="/doc/go_spec.html#Label_scopes">Unused labels are now illegal</a>, just as unused local variables are.</p> + +<h3 id="r57.pkg">Packages</h3> + +<p> +<a href="/pkg/gob/">Package gob</a> will now encode and decode values of types that implement the +<a href="/pkg/gob/#GobEncoder">GobEncoder</a> and +<a href="/pkg/gob/#GobDecoder">GobDecoder</a> interfaces. This allows types with unexported +fields to transmit self-consistent descriptions; examples include +<a href="/pkg/big/#Int.GobDecode">big.Int</a> and <a href="/pkg/big/#Rat.GobDecode">big.Rat</a>. +</p> + +<p> +<a href="/pkg/http/">Package http</a> has been redesigned. +For clients, there are new +<a href="/pkg/http/#Client">Client</a> and <a href="/pkg/http/#Transport">Transport</a> +abstractions that give more control over HTTP details such as headers sent +and redirections followed. These abstractions make it easy to implement +custom clients that add functionality such as <a href="http://code.google.com/p/goauth2/source/browse/oauth/oauth.go">OAuth2</a>. +For servers, <a href="/pkg/http/#ResponseWriter">ResponseWriter</a> +has dropped its non-essential methods. +The Hijack and Flush methods are no longer required; +code can test for them by checking whether a specific value implements +<a href="/pkg/http/#Hijacker">Hijacker</a> or <a href="/pkg/http/#Flusher">Flusher</a>. +The RemoteAddr and UsingTLS methods are replaced by <a href="/pkg/http/#Request">Request</a>'s +RemoteAddr and TLS fields. +The SetHeader method is replaced by a Header method; +its result, of type <a href="/pkg/http/#Header">Header</a>, +implements Set and other methods. +</p> + +<p> +<a href="/pkg/net/">Package net</a> +drops the <code>laddr</code> argument from <a href="/pkg/net/#Conn.Dial">Dial</a> +and drops the <code>cname</code> return value +from <a href="/pkg/net/#LookupHost">LookupHost</a>. +The implementation now uses <a href="/cmd/cgo/">cgo</a> to implement +network name lookups using the C library getaddrinfo(3) +function when possible. This ensures that Go and C programs +resolve names the same way and also avoids the OS X +application-level firewall. +</p> + +<p> +<a href="/pkg/os/">Package os</a> +introduces simplified <a href="/pkg/os/#File.Open">Open</a> +and <a href="/pkg/os/#File.Create">Create</a> functions. +The original Open is now available as <a href="/pkg/os/#File.OpenFile">OpenFile</a>. +The final three arguments to <a href="/pkg/os/#Process.StartProcess">StartProcess</a> +have been replaced by a pointer to a <a href="/pkg/os/#ProcAttr">ProcAttr</a>. +</p> + +<p> +<a href="/pkg/reflect/">Package reflect</a> has been redesigned. +<a href="/pkg/reflect/#Type">Type</a> is now an interface that implements +all the possible type methods. +Instead of a type switch on a Type <code>t</code>, switch on <code>t.Kind()</code>. +<a href="/pkg/reflect/#Value">Value</a> is now a struct value that +implements all the possible value methods. +Instead of a type switch on a Value <code>v</code>, switch on <code>v.Kind()</code>. +Typeof and NewValue are now called <a href="/pkg/reflect/#Type.TypeOf">TypeOf</a> and <a href="/pkg/reflect/#Value.ValueOf">ValueOf</a> +To create a writable Value, use <code>New(t).Elem()</code> instead of <code>Zero(t)</code>. +See <a href="http://code.google.com/p/go/source/detail?r=843855f3c026">the change description</a> +for the full details. +The new API allows a more efficient implementation of Value +that avoids many of the allocations required by the previous API. +</p> + +<p> +Remember that gofix will handle the bulk of the rewrites +necessary for these changes to package APIs. +</p> + +<h3 id="r57.cmd">Tools</h3> + +<p><a href="/cmd/gofix/">Gofix</a>, a new command, is described above.</p> + +<p> +<a href="/cmd/gotest/">Gotest</a> is now a Go program instead of a shell script. +The new <code>-test.short</code> flag in combination with package testing's Short function +allows you to write tests that can be run in normal or “short” mode; +all.bash runs tests in short mode to reduce installation time. +The Makefiles know about the flag: use <code>make testshort</code>. +</p> + +<p> +The run-time support now implements CPU and memory profiling. +Gotest's new +<a href="/cmd/gotest/"><code>-test.cpuprofile</code> and +<code>-test.memprofile</code> flags</a> make it easy to +profile tests. +To add profiling to your web server, see the <a href="/pkg/http/pprof/">http/pprof</a> +documentation. +For other uses, see the <a href="/pkg/runtime/pprof/">runtime/pprof</a> documentation. +</p> + +<h3 id="r57.minor">Minor revisions</h3> + +<p>r57.1 fixes a <a href="http://code.google.com/p/go/source/detail?r=ff2bc62726e7145eb2ecc1e0f076998e4a8f86f0">nil pointer dereference in http.FormFile</a>.</p> +<p>r57.2 fixes a <a href="http://code.google.com/p/go/source/detail?r=063b0ff67d8277df03c956208abc068076818dae">use of uninitialized memory in programs that misuse <code>goto</code></a>.</p> + +<h2 id="r56">r56 (released 2011/03/16)</h2> + +<p> +The r56 release was the first stable release and corresponds to +<code><a href="weekly.html#2011-03-07">weekly.2011-03-07.1</a></code>. +The numbering starts at 56 because before this release, +what we now consider weekly snapshots were called releases. +</p> diff --git a/doc/devel/roadmap.html b/doc/devel/roadmap.html new file mode 100644 index 000000000..d3c494715 --- /dev/null +++ b/doc/devel/roadmap.html @@ -0,0 +1,135 @@ +<!-- Roadmap --> + +<h2 id="Roadmap">Go Roadmap</h2> + +<p> +This page lists features and ideas being developed or discussed by the +Go team. This list will be updated as work continues. + +<p> +The roadmap should be discussed on +the <a href="http://groups.google.com/group/golang-nuts">golang-nuts +mailing list</a>. + +<h3 id="Language_roadmap"> +Language roadmap</h3> + +<p> +This is a list of language changes that are being considered. +Appearance on this list is no guarantee that the change will be +accepted. + +<ul> +<li> +Possibly rewrite restriction on goto across variable declarations. +<li> +Variant types. A way to define a type as being the union of some set +of types. +<li> +Generics. An active topic of discussion. +<li> +Methods for operators, to allow a type to use arithmetic notation for +expressions. +<li> +Possibly allow top-level packages to be given names other than main. +</ul> + +<h3 id="Implementation_roadmap"> +Implementation roadmap</h3> + +<ul> +<li> +Improved garbage collector. +<li> +Debugger. +<li> +Improved implementation documentation. +</ul> + +<h4 id="Gc_roadmap"> +Gc compiler roadmap</h4> + +<ul> +<li> +Implement goto restrictions. +<li> +Improved optimization. +<li> +Use escape analysis to keep more data on stack. +</ul> + +<h4 id="Gccgo_roadmap"> +Gccgo compiler roadmap</h4> + +<ul> +<li> +Implement goto restrictions. +<li> +Use goroutines rather than threads. +<li> +Separate gcc interface from frontend proper. +<li> +Use escape analysis to keep more data on stack. +</ul> + +<h4 id="Tools_roadmap"> +Tools roadmap</h4> + +<ul> +<li> +Strengthen goinstall until it can displace make for most builds. +</ul> + +<h4 id="Packages_roadmap"> +Packages roadmap</h4> + +<ul> +<li> +Faster, RE2-like regular expressions. +<li> +Comprehensive support for international text. +<li> +Support for international dates, times, etc. +<li> +Support for multilingual messages. +</ul> + + +<h3 id="done">Done</h3> + +<ul> +<li> +gc: Generate DWARF debug info. +<li> +gc: Provide gdb support for runtime facilities. +<li> +Safe compilation mode: generate code that is guaranteed not to obtain an invalid memory address other than via <code>import "unsafe"</code>. +<li> +Gccgo: garbage collection. +<li> +SWIG support. +<li> +Simpler semicolon rules. +<li> +A more general definition of <code>...</code> in parameter lists. +<li> +Explicit conversions from <code>string</code> +to <code>[]byte</code> and <code>[]int</code>. +<li> +A function that will be run by the garbage collector when an item is freed +(runtime.SetFinalizer). +<li> +Public continuous build and benchmark infrastructure (gobuilder). +<li> +Package manager (goinstall). +<li> +A means of recovering from a panic (recover). +<li> +5g: Better floating point support. +<li> +Improved CGO including some mechanism for calling back from C to Go. +<li> +Faster, allocation-light reflection. +<li> +App Engine support. +</ul> diff --git a/doc/devel/weekly.html b/doc/devel/weekly.html new file mode 100644 index 000000000..d984d3b1b --- /dev/null +++ b/doc/devel/weekly.html @@ -0,0 +1,3970 @@ +<!-- Weekly Snapshot History --> + +<p>This page summarizes the changes between tagged weekly snapshots of Go. +For full details, see the <a href="http://code.google.com/p/go/source/list">Mercurial change log</a>.</p> + +<p>Weekly snapshots occur often and may not be stable. +If stability of API and code is more important than having the +latest features, use the <a href="release.html">official releases</a> instead.</p> + +<p>To update to a specific snapshot, use:</p> + +<pre> +hg pull +hg update weekly.<i>YYYY-MM-DD</i> +</pre> + +<h2 id="2011-09-07">2011-09-07</h2> + +<pre> +This weekly snapshot consists of improvements and bug fixes, including fixes +for issues introduced by escape analysis changes in the gc compiler. + +* build: clear execute bit from Go files (thanks Mike Rosset), + error out if problem with sudo.bash /usr/local/bin (thanks Mike Rosset). +* exp/norm: add Reader and Writer, + performance improvements of quickSpan. +* exp/regexp: bug fixes and RE2 tests. +* exp/template/html: string replacement refactoring, + tweaks to js{,_test}.go. +* gc: add -p flag to catch import cycles earlier, + fix label recursion bugs, + fix zero-length struct eval, + zero stack-allocated slice backing arrays, +* gc, ld: fix Windows file paths (thanks Hector Chu). +* go/parser: accept corner cases of signature syntax. +* gobuilder: ignore _test.go files when looking for docs, more logging. +* godoc: minor tweaks for App Engine use. +* gofix: do not convert url in field names (thanks Gustavo Niemeyer). +* gofmt: indent multi-line signatures. +* gopprof: regexp fixes (thanks Hector Chu). +* image/png: check zlib checksum during Decode. +* libmach: fix incorrect use of memset (thanks Dave Cheney). +* misc/goplay: fix template output. +* net: ParseCIDR returns IPNet instead of IPMask (thanks Mikio Hara), + sync CIDRMask code, doc. +* os: use GetFileAttributesEx to implement Stat on windows (thanks Alex Brainman). +* runtime: fix openbsd 386 raisesigpipe, + implement exception handling on windows/amd64 (thanks Hector Chu), + test for concurrent channel consumers (thanks Christopher Wedgwood). +* sort: use heapsort to bail out quicksort (thanks Ziad Hatahet). +* sync/atomic: add LoadUintptr, add Store functions. +* syscall: update routing message attributes handling (thanks Mikio Hara). +* template: fix deadlock, + indirect or dereference function arguments if necessary, + slightly simplify the test for assignability of arguments. +* url: handle ; in ParseQuery. +* websocket: fix incorrect prints found by govet (thanks Robert Hencke). +</pre> + +<h2 id="2011-09-01">2011-09-01</h2> + +<pre> +This weekly contains performance improvements and bug fixes. + +The gc compiler now does escape analysis, which improves program performance +by placing variables on the call stack instead of the heap when it is safe to +do so. + +The container/vector package is deprecated and will be removed at some point +in the future. + +Other changes: +* archive/tar: support symlinks. (thanks Mike Rosset) +* big: fix nat.scan bug. (thanks Evan Shaw) +* bufio: handle a "\r\n" that straddles the buffer. + add openbsd. + avoid redundant bss declarations. + fix unused parameters. + fix windows/amd64 build with newest mingw-w64. (thanks Hector Chu) +* bytes: clarify that NewBuffer is not for beginners. +* cgo: explain how to free something. + fix GoBytes. (thanks Gustavo Niemeyer) + fixes callback for windows amd64. (thanks Wei Guangjing) + note that CString result must be freed. (thanks Gustavo Niemeyer) +* cov: remove tautological #defines. (thanks Lucio De Re) +* dashboard: yet another utf-8 fix. +* doc/codelab/wiki: fix Makefile. +* doc/progs: fix windows/amd64. (thanks Jaroslavas Počepko) +* doc/tmpltohtml: update to new template package. +* doc: emphasize that environment variables are optional. +* effective_go: convert to use tmpltohtml. +* exp/norm: reduced the size of the byte buffer used by reorderBuffer by half by reusing space when combining. + a few minor fixes to support the implementation of norm. + added implementation for []byte versions of methods. +* exp/template/html: add some tests for ">" attributes. + added handling for URL attributes. + differentiate URL-valued attributes (such as href). + reworked escapeText to recognize attr boundaries. +* exp/wingui: made compatible with windows/amd64. (thanks Jaroslavas Počepko) +* flag: add Parsed, restore Usage. +* gc: add openbsd. + escape analysis. + fix build on Plan 9. (thanks Lucio De Re) + fix div bug. + fix pc/line table. (thanks Julian Phillips) + fix some spurious leaks. + make static initialization more static. + remove JCXZ; add JCXZW, JCXZL, and JCXZQ instructions. (thanks Jaroslavas Počepko) + shuffle #includes. + simplify escape analysis recursion. + tweak and enable escape analysis. +* go/ast cleanup: base File/PackageExports on FilterFile/FilterPackage code. + adjustments to filter function. + fix ast.MergePackageFiles to collect infos about imports. (thanks Sebastien Binet) + generalize ast.FilterFile. +* go/build: add test support & use in gotest. + separate test imports out when scanning. (thanks Gustavo Niemeyer) +* go/parser: fix type switch scoping. + fix type switch scoping. +* gob: explain that Debug isn't useful unless it's compiled in. +* gobuilder: increase log limit. +* godashboard: fix utf-8 in user names. +* godoc: first step towards reducing index size. + add dummy playground.js to silence godoc warning at start-up. + added systematic throttling to indexing goroutine. + fix bug in zip.go. + support for reading/writing (splitted) index files. + use virtual file system when generating package synopses. +* gofix: forgot to rename the URL type. + osopen: fixed=true when changing O_CREAT. (thanks Tarmigan Casebolt) +* goinstall: error out with paths that end with '/'. (thanks Tarmigan Casebolt) + report lack of $GOPATH on errors. (thanks Gustavo Niemeyer) + select the tag that is closest to runtime.Version. +* gotry: add missing $. (thanks Tarmigan Casebolt) +* http: add MaxBytesReader to limit request body size. + add file protocol transport. + adjust test threshold for larger suse buffers. + delete error kludge. + on invalid request, send 400 response. + return 413 instead of 400 when the request body is too large. (thanks Dave Cheney) + support setting Transport's TLS client config. +* image/tiff: add a decode benchmark. (thanks Benny Siegert) + decoder optimization. (thanks Benny Siegert) +* image: add PalettedImage interface, and make image/png recognize it. (thanks Jaroslavas Počepko) +* io: add TeeReader. (thanks Hector Chu) +* json: add struct tag option to wrap literals in strings. + calculate Offset for Indent correctly. (thanks Jeff Hodges) + fix decode bug with struct tag names with ,opts being ignored. +* ld: handle Plan 9 ar format. (thanks Lucio De Re) + remove duplicate bss definitions. +* libmach: support reading symbols from Windows .exe for nm. (thanks Mateusz Czapliński) +* math: fix Pow10 loop. (thanks Volker Dobler) +* mime: ParseMediaType returns os.Error now, not a nil map. + media type formatter. (thanks Pascal S. de Kloe) + text charset defaults. (thanks Pascal S. de Kloe) +* misc/dashboard: remove limit for json package list. +* misc/emacs: refine label detection. +* net: add ParseMAC function. (thanks Paul Borman) + change the internal form of IPMask for IPv4. (thanks Mikio Hara) + disable "tcp" test on openbsd. + fix windows build. (thanks Alex Brainman) + join and leave a IPv6 group address, on a specific interface. (thanks Mikio Hara) + make use of IPv4len, IPv6len. (thanks Mikio Hara) + move internal string manipulation routines to parse.go. (thanks Mikio Hara) +* os: disable Hostname test on OpenBSD. + fix WNOHANG Waitmsg. (thanks Gustavo Niemeyer) +* reflect: add Value.Bytes, Value.SetBytes methods. +* rpc: add benchmark for async rpc calls. +* runtime: add openbsd 386 defs.h. + add runtime support for openbsd 386. + add runtime· prefix to showframe. + ctrlhandler for windows amd64. (thanks Wei Guangjing) + fix stack cleanup on windows/amd64. (thanks Hector Chu) + fix void warnings. + go interface to cdecl calbacks. (thanks Jaroslavas Počepko) + handle string + char literals in goc2c. + make arm work on Ubuntu Natty qemu. + openbsd thread tweaks. + simplify stack traces. + speed up cgo calls. (thanks Alex Brainman) + use cgo runtime functions to call windows syscalls. (thanks Alex Brainman) + windows/amd64 callbacks fixed and syscall fixed to allow using it in callbacks. (thanks Jaroslavas Počepko) +* strconv: put decimal on stack. +* spec: update section on Implementation Differences. +* syscall: SOMAXCONN should be 0x7fffffff at winsock2. (thanks Yasuhiro Matsumoto) + add openbsd 386. + handle RTM_NEWROUTE in ParseNetlinkRouteAttr on Linux. (thanks Albert Strasheim) + handle routing entry in ParseRoutingSockaddr on BSD variants. (thanks Mikio Hara) + openbsd amd64 syscall support. + use the vdso page on linux x86 for faster syscalls instead of int $0x80. (thanks Yuval Pavel Zholkover) +* template/parse: give if, range, and with a common representation. +* template: grammar fix for template documentation. (thanks Bill Neubauer) + range over channel. + remove else and end nodes from public view. +* test: put GOROOT/bin before all others in run. +* time: fix Plan 9 build. (thanks Fazlul Shahriar) + fix zone during windows test. +* type switches: test for pathological case. +* version.bash: update VERSION on -save if already present. (thanks Gustavo Niemeyer) +* websocket: implements new version of WebSocket protocol. (thanks Fumitoshi Ukai) +* windows/386: clean stack after syscall. (thanks Jaroslavas Počepko) +* xml: marshal "parent>child" tags correctly. (thanks Ross Light) +</pre> + +<h2 id="2011-08-17">2011-08-17 (<a href="release.html#r60">base for r60</a>)</h2> + +<pre> +This weekly contains some package re-shuffling. Users of the http and +template packages may be affected. + +This weekly replaces the template package with exp/template. +The original template package is still available as old/template. +The old/template package is deprecated and will be removed at some point +in the future. The Go tree has been updated to use the new template package. +We encourage users of the old template package to switch to the new one. +Code that uses template or exp/template will need to change +its import lines to "old/template" or "template", respectively. + +The http package's URL parsing and query escaping code (such as ParseURL and +URLEscape) has been moved to the new url package, with several simplifications +to the names. Client code can be updated automatically with gofix. + +* asn1: support unmarshalling structs with int32 members (thanks Dave Cheney). +* build: allow builds without cgo or hg, + support versioning without hg (thanks Gustavo Niemeyer). +* builtin: add documentation for builtins. +* cgo: omit duplicate symbols in writeDefs (thanks Julian Phillips). +* misc: add support for OpenBSD. +* doc/codewalk: new Markov chain codewalk. +* exp/norm: added trie lookup code and associated tests, + generate trie struct in triegen.go for better encapsulation, + implementation of decomposition and composing functionality. +* exp/template/html: new experimental package for auto-escaping HTML templates. +* exp/template: don't panic on range of nil interface, + rename Parse*File and Parse*Files for clarity, + support field syntax on maps (thanks Gustavo Niemeyer), and + many other fixes and changes. +* gc: implement nil chan and nil map support. +* go/parser: range clause and type literal fixes. +* godoc: show all top-level decls for (fake) package builtin. +* goinstall: really report all newly-installed public packages. +* html: parse more malformed tags. +* http: fix ParseMultipartForm after MultipartReader error, + fix side effects in DefaultTransport's RoundTrip method (thanks Dave Grijalva). +* json: fix []unmarshaler case. +* ld: make addaddrplus4 static (thanks Lucio De Re). +* syscall: move multicast address handling to the net package. +* net: Plan 9 support (thanks Fazlul Shahriar), + add SetTimeout to Listener interface (thanks Aleksandar Dezelin), + add multicast stubs for OpenBSD, + return correct local address for an accepted TCP connection (thanks Mikio Hara). +* reflect: panic on Invalid Interface call (thanks Gustavo Niemeyer). +* rpc: implement ServeRequest to synchronously serve a single request, + make Server.Mutex unexported. +* runtime: better checks for syscall.NewCallback parameter (thanks Alex Brainman), + correct SEH installation during callbacks (thanks Alex Brainman), + fix GC bitmap corruption, + fix pseudo-randomness on some selects (thanks Gustavo Niemeyer). +* syscall: make LazyDLL/LazyProc.Mutex unexported. +* test: allow multiple patterns in errchk, + new nil semantics. +* time: take fractional seconds even if not in the format string. +* url: new package. +* utf8: rename some internal constants to remove leading underscores. +* xml: escape string chardata in xml.Marshal. +</pre> + +<h2 id="2011-08-10">2011-08-10</h2> + +<pre> +This weekly contains performance improvements and bug fixes. + +There are no outward-facing changes, but imports of the old-style +container/vector package have also been removed from the core library (thanks +John Asmuth, Kyle Consalus). + +Other changes: + +* 5g: fix set but not used error (thanks Dave Cheney). +* cmd/ld: Corrected mismatched print formats and variables (thanks Lucio De Re). +* errchk: add -0 flag. +* exp/norm: fix build by adding a test placeholder, + maketables tool for generating tables for normalization. +* exp/template: bug fixes, + ensure that a valid Set is returned even on error (thanks Roger Peppe), + make index on maps return zero when key not present (thanks Roger Peppe), + split the parse tree into a separate package exp/template/parse, + add url query formatting filter. +* faq: lots of small tweaks plus a couple of new discussions, + variant types, unions. +* fmt: call UpdateMemStats in malloc counter. +* go/build: use GOBIN as binary path for GOROOT. +* gob: add UpdateMemStats calls to malloc counter, + avoid a couple of init-time allocations, + don't invoke GobEncoder on zero values. +* gofmt: update test script so 'make test' succeeds. +* html: parse doctype tokens; merge adjacent text nodes. +* http: add more MPEG-4 MIME types to sniffer, and disable MP4 sniffing, + add test to serve content in index.html (thanks Yasuhiro Matsumoto), + configurable and default request header size limit, + correct format flags when printing errors in tests (thanks Alex Brainman), + correct path to serve index.html (thanks Yasuhiro Matsumoto), +* ld: add one empty symbol into pe to make dumpbin works (thanks Wei Guangjing), + fail linking if the top-level package is not main. +* misc/vim: godoc command (thanks Yasuhiro Matsumoto). +* net: add support for openbsd (thanks Joel Sing), + fix /proc/net/igmp,igmp6 reading bug on linux (thanks Mikio Hara), + implement windows LookupMX and LookupAddr (thanks Mikio Hara), + sort SRV records before returning from LookupSRV (thanks Alex Brainman), +* os: add support for openbsd (thanks Joel Sing). +* runtime: add more specialized type algorithms, + correct Note documentation, + faster chan creation on Linux/FreeBSD/Plan9, + openbsd amd64 runtime support (thanks Joel Sing), + remove unnecessary locking (thanks Hector Chu). +* scanner: correct error position for illegal UTF-8 encodings. +* syscall: delay load of dll functions on Windows (thanks Alex Brainman), + move BSD mmap syscall (thanks Joel Sing), + update routing message support for BSD variants (thanks Mikio Hara). +* test/bench: note changes after recent improvements to locking and runtime. +* time: add nanoseconds to the Time structure, + parse and format fractional seconds. +</pre> + +<h2 id="2011-07-29">2011-07-29</h2> + +<pre> +This weekly contains performance improvements and many bug fixes. + +* 6l: OpenBSD support. +* archive/zip: handle zip files with more than 65535 files, + more efficient reader and bug fix. +* big: refine printf formatting and optimize string conversion. +* build: fixes for mingw-w64 (thanks Wei Guangjing), + miscellaneous fixes. +* cgo: add GoBytes, fix gmp example. +* exp/norm: API for normalization library. +* exp/regexp: implement regexp API using exp/regexp/syntax. +* exp/template: more tweaks and fixes, convert the tree to use exp/template. +* fmt: handle precision 0 format strings in standard way. +* gc: a raft of bug fixes. +* go/parser: report illegal label declarations at ':'. +* gob: send empty but non-nil maps. +* godoc: allow form feed in text files, + app engine configuration and updated documentation. +* goinstall: abort and warn when using any url scheme, not just 'http://', + write to goinstall.log in respective GOPATH. +* html: handle character entities without semicolons (thanks Andrew Balholm), + parse misnested formatting tags according to the HTML5 spec, + sync html/testdata/webkit with upstream WebKit. +* http: content-type sniffing, + make serveFile redirects relative (thanks Andrew Balholm), + other fixes. +* image/tiff: Do not panic when RowsPerStrip is missing (thanks Benny Siegert). +* io/ioutil: improve performance of ioutil.Discard (thanks Mike Solomon). +* ld: detect all import cycles, + ldpe fixes (thanks Wei Guangjing), + remove cseekend and redo pe writing (thanks Alex Brainman), + remove overlap of ELF sections on dynamic binaries (thanks Gustavo Niemeyer). +* net/textproto: avoid 1 copy in ReadLine, ReadContinuedLine. +* net: fix memory corruption in windows *netFD.ReadFrom (thanks Alex Brainman). +* runtime: faster entersyscall/exitsyscall, + fix scheduler races (thanks Hector Chu), + higher goroutine arg limit, clearer error, + parallelism-related performance optimizations and fixes, + replace byte-at-a-time zeroing loop with memclr (thanks Quan Yong Zhai). +* sort: fix Float64Slice sort; NaN smallest value (thanks Florian Uekermann). +* src: removed some uses of container/vector (thanks John Asmuth). +* sync: improve Once fast path. +* unicode: fix case-mapping for roman numerals. +</pre> + +<h2 id="2011-07-19">2011-07-19</h2> + +<pre> +This weekly snapshot includes a language change and a change to the image +package that may require changes to client code. + +The language change is that an "else" block is now required to have braces +except if the body of the "else" is another "if". Since gofmt always puts those +braces in anyway, programs will not be affected unless they contain "else for", +"else switch", or "else select". Run gofmt to fix any such programs. + +The image package has had significant changes made to the Pix field of struct +types such as image.RGBA and image.NRGBA. The image.Image interface type has +not changed, though, and you should not need to change your code if you don't +explicitly refer to Pix fields. For example, if you decode a number of images +using the image/jpeg package, compose them using image/draw, and then encode +the result using image/png, then your code should still work as before. + +If you do explicitly refer to Pix fields, there are two changes. First, Pix[0] +now refers to the pixel at Bounds().Min instead of the pixel at (0, 0). Second, +the element type of the Pix slice is now uint8 instead of image.FooColor. For +example, for an image.RGBA, the channel values will be packed R, G, B, A, R, G, +B, A, etc. For 16-bits-per-channel color types, the pixel data will be stored +as big-endian uint8s. + +Most Pix field types have changed, and so if your code still compiles after +this change, then you probably don't need to make any further changes (unless +you use an image.Paletted's Pix field). If you do get compiler errors, code +that used to look like this: + + // Get the R, G, B, A values for the pixel at (x, y). + var m *image.RGBA = loadAnImage() + c := m.Pix[y*m.Stride + x] + r, g, b, a := c.R, c.G, c.B, c.A + +should now look like this: + + // Get the R, G, B, A values for the pixel at (x, y). + var m *image.RGBA = loadAnImage() + i := (y-m.Rect.Min.Y)*m.Stride + (x-m.Rect.Min.X)*4 + r := m.Pix[i+0] + g := m.Pix[i+1] + b := m.Pix[i+2] + a := m.Pix[i+3] + +This image package change will not be fixed by gofix: how best to translate +code into something efficient and idiomatic depends on the surrounding context, +and is not easily automatable. Examples of what to do can be found in the +changes to image/draw/draw.go in http://codereview.appspot.com/4675076/ + +Other changes: +* 6l: change default output name to 6.out.exe on windows (thanks Alex Brainman). +* archive/zip: add Writer, + add Mtime_ns function to get modified time in sensible format. +* cc, ld, gc: fixes for Plan 9 build (thanks Lucio De Re). +* cgi: close stdout reader pipe when finished. +* cgo: add missing semicolon in generated struct, + windows amd64 port (thanks Wei Guangjing). +* codereview: fix for Mercurial 1.9. +* dashboard: list "most installed this week" with rolling count. +* debug/elf: read ELF Program headers (thanks Matthew Horsnell). +* debug/pe: fixes ImportedSymbols for Win64 (thanks Wei Guangjing). +* debug/proc: remove unused package. +* doc/talks/io2010: update with gofix and handle the errors. +* exp/eval, exp/ogle: remove packages eval and ogle. +* exp/regexp/syntax: add Prog.NumCap. +* exp/template: API changes, bug fixes, and tweaks. +* flag: make -help nicer. +* fmt: Scan(&int) was mishandling a lone digit. +* gc: fix closure bug, + fix to build with clang (thanks Dave Cheney), + make size of struct{} and [0]byte 0 bytes (thanks Robert Hencke), + some enhancements to printing debug info. +* gif: fix local color map and coordinates. +* go/build: fixes for windows (thanks Alex Brainman), + include processing of .c files for cgo packages (thanks Alex Brainman), + less aggressive failure when GOROOT not found. +* go/printer: changed max. number of newlines from 3 to 2. +* gob: register more slice types (thanks Bobby Powers). +* godoc: support for file systems stored in .zip files. +* goinstall, dashboard: Google Code now supports git (thanks Tarmigan Casebolt). +* hash/crc32: add SSE4.2 support. +* html: update section references in comments to the latest HTML5 spec. +* http: drain the pipe output in TestHandlerPanic to avoid logging deadlock, + fix Content-Type of file extension (thanks Yasuhiro Matsumoto), + implement http.FileSystem for zip files, + let FileServer work when path doesn't begin with a slash, + support for periodic flushing in ReverseProxy. +* image/draw: add benchmarks. +* json: add omitempty struct tag option, + allow using '$' and '-' as the struct field's tag (thanks Mikio Hara), + encode \r and \n in strings as e.g. "\n", not "\u000A" (thanks Evan Martin), + escape < and > in any JSON string for XSS prevention. +* ld: allow seek within write buffer< + add a PT_LOAD PHDR entry for the PHDR (thanks David Anderson). +* net: windows/amd64 port (thanks Wei Guangjing). +* os: plan9: add Process.Signal as a way to send notes (thanks Yuval Pavel Zholkover). +* os: don't permit Process.Signal after a successful Wait. +* path/filepath: fixes for windows paths (thanks Alex Brainman). +* reflect: add Value.NumMethod, + panic if Method index is out of range for a type. +* runtime: faster entersyscall, exitsyscall, + fix panic for make(chan [0]byte), + fix subtle select bug (thanks Hector Chu), + make goc2c build on Plan 9 (thanks Lucio De Re), + make TestSideEffectOrder work twice, + several parallelism-related optimizations and fixes, + stdcall_raw stack 16byte align for Win64 (thanks Wei Guangjing), + string-related optimizations (thanks Quan Yong Zhai), + track running goroutine count. +* strconv: handle [-+]Infinity in atof. +* sync: add fast paths to WaitGroup, + improve RWMutex performance. +* syscall: add Flock on Linux, + parse and encode SCM_RIGHTS and SCM_CREDENTIALS (thanks Albert Strasheim). +</pre> + +<h2 id="2011-07-07">2011-07-07 (<a href="release.html#r59">base for r59</a>)</h2> + +<pre> +This weekly snapshot includes changes to the strings, http, reflect, json, and +xml packages. Code that uses these packages will need changes. Most of these +changes can be made automatically with gofix. + +The strings package's Split function has itself been split into Split and +SplitN. SplitN is the same as the old Split. The new Split is equivalent to +SplitN with a final argument of -1. + +The http package has a new FileSystem interface that provides access to files. +The FileServer helper now takes a FileSystem argument instead of an explicit +file system root. By implementing your own FileSystem you can use the +FileServer to serve arbitrary data. + +The reflect package supports a new struct tag scheme that enables sharing of +struct tags between multiple packages. +In this scheme, the tags must be of the form: + key:"value" key2:"value2" +reflect.StructField's Tag field now has type StructTag (a string type), which +has method Get(key string) string that returns the associated value. +Clients of json and xml will need to be updated. Code that says + type T struct { + X int "name" + } +should become + type T struct { + X int `json:"name"` // or `xml:"name"` + } +Use govet to identify struct tags that need to be changed to use the new syntax. + +Other changes: +* 5l, 6l, 8l: drop use of ed during build. +* asn1: support T61 and UTF8 string. +* bufio: do not cache Read errors (thanks Graham Miller). +* build: make version.bash aware of branches. +* cgi: don't depend on CGI.pm for tests. +* codereview: make --ignore_hgpatch_failure work again, + restrict sync to default branch. +* crypto/openpgp: add ability to reserialize keys, + bug fix (thanks Gideon Jan-Wessel Redelinghuys). +* crypto/tls: fix generate_cert.go. +* crypto/x509: prevent chain cycles in Verify. +* csv: new package. +* doc: remove ed from apt-get package list. +* docs: fold the prog.sh scripting from makehtml into htmlgen itself. +* ebnflint: better handling of stdin. +* exp/regexp/syntax: new experimental RE2-based regexp implementation. +* exp/template: a new experimental templating package. +* fmt: add SkipSpace to fmt's ScanState interface. +* fmt: rename errno and error to err for doc consistency. +* gc: avoid package name ambiguity in error messages, + fix package quoting logic, + fixes for Plan 9 (thanks Lucio De Re). +* go/build: evaluate symlinks before comparing path to GOPATH. +* gob: use exported fields in structs in the package documentation. +* godoc: ignore directories that begin with '.', + search GOPATH for documentation. +* gofix: os/signal, path/filepath, and sort fixes (thanks Robert Hencke), +* goinstall: add support for generic hosts (thanks Julian Phillips), + only report successfully-installed packages to the dashboard, + try to access via https (thanks Yasuhiro Matsumoto). +* gotest: add -test.benchtime and -test.cpu flags. +* html: fixes and improvements (thanks Yasuhiro Matsumoto). +* http/cgi: add Handler.Dir to specify working directory (thanks Yasuhiro Matsumoto). +* http: add StripPrefix handler wrapper, + assume ContentLength 0 on GET requests, + better handling of 0-length Request.Body, + do TLS handshake explicitly before copying TLS state, + document that ServerConn and ClientConn are low-level, + make NewChunkedReader public (thanks Andrew Balholm), + respect Handlers setting Connection: close in their response. +* image: more tests, Paletted.Opaque optimization. +* io.WriteString: if the object has a WriteString method, use it (thanks Evan Shaw). +* ld: elide the Go symbol table when using -s (thanks Anthony Martin). +* ld: fix ELF strip by removing overlap of sections (thanks Gustavo Niemeyer). +* mime/multipart: parse LF-delimited messages, not just CRLF. +* mime: permit lower-case media type parameters (thanks Pascal S. de Kloe). +* misc/dashboard: new features and improvements (not yet deployed). +* misc/emacs: update list of builtins (thanks Quan Yong Zhai). +* misc/vim: allow only utf-8 for file encoding (thanks Yasuhiro Matsumoto). +* os: fix documentation for FileInfo.Name, + simplify WriteString, + use a different symbol from syscall in mkunixsignals.sh. +* path/filepath: enable TestWalk to run on windows (thanks Alex Brainman). +* reflect: add MethodByName, + allow Len on String values. +* regexp: document that Regexp is thread-safe. +* runtime/cgo: check for errors from pthread_create (thanks Albert Strasheim). +* runtime: add Semacquire/Semrelease benchmarks, + improved Semacquire/Semrelease implementation, + windows/amd64 port (thanks Wei Guangjing). +* sync: add fast path to Once, + improve Mutex to allow successive acquisitions, + new and improved benchmarks. +* syscall: regenerate zerrors for darwin/linux/freebsd, + support for tty options in StartProcess (thanks Ken Rockot). +* testing: make ResetTimer not start/stop the timer, + scale benchmark precision to 0.01ns if needed. +* time: zero-pad two-digit years. +* unicode/maketables: update debugging data. +* windows: define and use syscall.Handle (thanks Wei Guangjing). +* xml: add Marshal and MarshalIndent. +</pre> + +<h2 id="2011-06-23">2011-06-23</h2> + +<pre> +This release includes a language change that restricts the use of goto. +In essence, a "goto" statement outside a block cannot jump to a label inside +that block. Your code may require changes if it uses goto. +This changeset shows how the new rule affected the Go tree: + http://code.google.com/p/go/source/detail?r=dc6d3cf9279d + +The os.ErrorString type has been hidden. If your code uses os.ErrorString it +must be changed. Most uses of os.ErrorString can be replaced with os.NewError. + +Other changes: +* 5c: do not use R9 and R10. +* 8l: more fixes for Plan 9 (thanks Lucio De Re). +* build: Make.ccmd: link with mach lib (thanks Joe Poirier). +* build: exclude packages that fail on Plan 9 (thanks Anthony Martin). +* cc: nit: silence comment warnings (thanks Dave Cheney). +* codereview.py: note that hg change -d abandons a change list (thanks Robert Hencke). +* crypto/openpgp: add ElGamal support. +* doc/faq: add question about converting from []T to []interface{}. +* doc: Effective Go: fix variadic function example (thanks Ben Lynn). +* exec: LookPath should not search %PATH% for files like c:cmd.exe (thanks Alex Brainman), + add support for Plan 9 (thanks Anthony Martin), + better error message for windows LookPath (thanks Alex Brainman). +* fmt: catch panics from calls to String etc. +* gc: descriptive panic for nil pointer -> value method call, + implement goto restriction, + unsafe.Alignof, unsafe.Offsetof, unsafe.Sizeof now return uintptr. +* go/build: include Import objects in Script Inputs. +* godefs: rudimentary tests (thanks Robert Hencke). +* goinstall: refactor and generalize repo handling code (thanks Julian Phillips), + temporarily use Makefiles by default (override with -make=false). +* gopprof: update list of memory allocators. +* http: add Server.ListenAndServeTLS, + buffer request.Write, + fix req.Cookie(name) with cookies in one header, + permit handlers to explicitly remove the Date header, + write Header keys with empty values. +* image: basic test for the 16-bits-per-color-channel types. +* io: clarify Read, ReadAt, Copy, Copyn EOF behavior. +* ld: don't attempt to build dynamic sections unnecessarily (thanks Gustavo Niemeyer). +* libmach: fix disassembly of FCMOVcc and FCOMI (thanks Anthony Martin), + fix tracing on linux (for cov) (thanks Anthony Martin). +* mime: fix RFC references (thanks Pascal S. de Kloe). +* misc/gobuilder: run make single-threaded on windows (thanks Alex Brainman). +* misc/godashboard: Accept sub-directories for goinstall's report (thanks Yasuhiro Matsumoto). +* nacl, tiny: remove vestiges (thanks Robert Hencke). +* net, syscall: interface for windows (thanks Yasuhiro Matsumoto). +* os: change Waitmsg String method to use pointer receiver (thanks Graham Miller). +* runtime: don't use twice the memory with grsec-like kernels (thanks Gustavo Niemeyer), +* spec: disallow goto into blocks. +* sync: restore GOMAXPROCS during benchmarks. +* syscall: add LSF support for linux (thanks Mikio Hara), + add socket control message support for darwin, freebsd, linux (thanks Mikio Hara), + add tty support to StartProcess (thanks Ken Rockot), + fix build for Sizeof change. +* test: test of goto restrictions. +* time: add support for Plan 9 (thanks Anthony Martin). +</pre> + +<h2 id="2011-06-16">2011-06-16</h2> + +<pre> +This release includes changes to the sort and image/draw packages that will +require changes to client code. + +The sort.IntArray type has been renamed to IntSlice, and similarly for +StringArray and Float64Array. + +The image/draw package's Draw function now takes an additional argument, +a compositing operator. If in doubt, use draw.Over. + +Other changes: +* build: fix header files for Plan 9 (thanks Lucio De Re). +* cgo: handle new Apple LLVM-based gcc from Xcode 4.2. +* crypto/openpgp: add ability to encrypt and sign messages. +* doc/gopher: add goggled gopher logo for App Engine. +* doc: Update notes for 3-day Go course. +* exec: make LookPath work when PATHEXT var not set on Windows (thanks Alex Brainman). +* exp/regexp/syntax: syntax data structures, parser, escapes, character classes. +* exp/template: lexical scanner for new template package. +* fmt: debugging formats for characters: %+q %#U. +* gc: frame compaction for arm, + handle go print() and go println(), + work around goto bug. +* go/build: fixes, self-contained tests. +* go/printer, gofmt: print "select {}" on one line. +* godoc: replace OS file system accesses in favor of a FileSystem interface. +* gofix: fix inconsistent indentation in help output (thanks Scott Lawrence). +* goinstall: use go/build package to scan and build packages. +* http/spdy: improve error handling (thanks William Chan). +* http: use runtime/debug.Stack() to dump stack trace on panic. +* ld: dwarf emit filenames in debug_line header instead of as extended opcodes, + fix link Windows PE __declspec(dllimport) symbol (thanks Wei Guangjing), + make .rodata section read-only (thanks Gustavo Niemeyer). +* mail: decode RFC 2047 "B" encoding. +* mime/multipart: remove temp files after tests on Windows (thanks Alex Brainman). +* net: export all fields in Interface (thanks Mikio Hara), + rearrange source to run more tests on Windows (thanks Alex Brainman), + sendfile for win32 (thanks Yasuhiro Matsumoto). +* os: Plan 9, fix OpenFile & Chmod, add Process.Kill (thanks Yuval Pavel Zholkover). +* runtime: fix Plan 9 "lingering goroutines bug" (thanks Yuval Pavel Zholkover). +* spec: clarify rules for append, scope rules for :=, + specify constant conversions, + unsafe.Alignof/Offsetof/Sizeof return uintptr. +* syscall, os, exec: add *syscall.SysProcAttr field to os.ProcAttr and exec.Cmd. +* syscall: add ptrace on darwin (thanks Jeff Hodges), + mksyscall_windows.pl should output unix newline (thanks Yasuhiro Matsumoto). + update BPF support for BSD variants (thanks Mikio Hara), + use strict in perl scripts (thanks Yasuhiro Matsumoto). +* xml: handle non-string attribute fields (thanks Maxim Ushakov). +</pre> + +<h2 id="2011-06-09">2011-06-09 (<a href="release.html#r58">base for r58</a>)</h2> + +<pre> +This release includes changes to the strconv, http, and exp/draw packages. +Client code that uses the http or exp/draw packages will need to be changed, +and code that uses strconv or fmt's "%q" formatting directive merits checking. + +The strconv package's Quote function now escapes only those Unicode code points +not classified as printable by unicode.IsPrint. Previously Quote would escape +all non-ASCII characters. This also affects the fmt package's "%q" formatting +directive. The previous quoting behavior is still available via strconv's new +QuoteToASCII function. + +Most instances of the type map[string][]string in the http package have been +replaced with the new Values type. The http.Values type has the Get, Set, Add, +and Del helper methods to make working with query parameters and form values +more convenient. + +The exp/draw package has been split into the image/draw and exp/gui packages. + +Other changes: +* 8l, ld: initial adjustments for Plan 9 native compilation of 8l (thanks Lucio De Re). +* arm: floating point improvements (thanks Fan Hongjian). +* big: Improved speed of nat-to-string conversion (thanks Michael T. Jones), + Rat outputs the requested precision from FloatString (thanks Graham Miller), + gobs for big.Rats. +* cgo: support non intel gcc machine flags (thanks Dave Cheney). +* compress/lzw: do not use background goroutines, + reduce decoder buffer size from 3*4096 to 2*4096. +* crypto/twofish: fix Reset index overflow bug. +* crypto: reorg, cleanup and add function for generating CRLs. +* exec: export the underlying *os.Process in Cmd. +* gc: enable building under clang/2.9 (thanks Dave Cheney), + preparatory work toward escape analysis, compact stack frames. +* go/build: new incomplete package for building go programs. +* godefs: do not assume forward type references are enums (thanks Robert Hencke). +* gofix, gofmt: fix diff regression from exec change. +* html: improve attribute parsing, note package status. +* http: don't fail on accept hitting EMFILE, + fix handling of 0-length HTTP requests. +* image/draw: fix clipping bug where sp/mp were not shifted when r.Min was. +* image/gif: fix buglet in graphics extension. +* image/tiff: support for bit depths other than 8 (thanks Benny Siegert). +* ld: fix and simplify ELF symbol generation (thanks Anthony Martin) +* libmach: use the standardized format for designated initializers (thanks Jeff Hodges) +* mail: address list parsing. +* net: add network interface identification API (thanks Mikio Hara), + fix bug in net.Interfaces: handle elastic sdl_data size correctly (thanks Mikio Hara). +* netchan: added drain method to importer (thanks David Jakob Fritz). +* os: add Process.Kill and Process.Signal (thanks Evan Shaw), + fix Getenv for Plan 9 (thanks Yuval Pavel Zholkover). +* runtime: improve memmove by checking memory overlap (thanks Quan Yong Zhai), + support for Linux grsecurity systems (thanks Jonathan Mark). +* spec: handle a corner case for shifts. +* testing: check that tests and benchmarks do not affect GOMAXPROCS (thanks Dmitriy Vyukov). +* unicode: add IsPrint and related properties, general categories. +</pre> + +<h2 id="2011-06-02">2011-06-02</h2> + +<pre> +This release includes changes to the exec package that will require changes +to client code. + +The exec package has been re-designed with a more convenient and succinct API. +This code: + args := []string{"diff", "-u", "file1.txt", "file2.txt"} + p, err := exec.Run("/usr/bin/diff", args, os.Environ(), "", + exec.DevNull, exec.Pipe, exec.DevNull) + if err != nil { + return nil, err + } + var buf bytes.Buffer + io.Copy(&buf, p.Stdout) + w, err := p.Wait(0) + p.Close() + if err != nil { + return nil, err + } + return buf.Bytes(), err +can be rewritten as: + return exec.Command("diff", "-u", "file1.txt", "file2.txt").Output() +See the exec package documentation for the details ("godoc exec"). + +By setting the GOPATH environment variable you can use goinstall to build and +install your own code and external libraries outside of the Go tree (and avoid +writing Makefiles). +See the goinstall command documentation for the details ("godoc goinstall"). + +Other changes: +* 5g: alignment fixes. +* 6l, 8l: fix Mach-O binaries with many dynamic libraries. +* 8l: emit resources (.rsrc) in Windows PE. (thanks Wei Guangjing). +* asn1: fix marshalling of empty optional RawValues (thanks Mikkel Krautz). +* big: make Int and Rat implement fmt.Scanner (thanks Evan Shaw), + ~8x faster number scanning, + remove some unnecessary conversions. +* cgo: restrict #cgo directives to prevent shell expansion (thanks Gustavo Niemeyer), + support pkg-config for flags and libs (thanks Gustavo Niemeyer). +* compress/flate: fix Huffman tree bug, + do not use background goroutines. +* crypto/openpgp: add support for symmetrically encrypting files. +* crypto/tls/generate_cert.go: fix misspelling of O_CREATE. +* dashboard: send notification emails when the build breaks. +* doc: mention go/printer instead of container/vector in effective go, + put Release History link on 'Documentation' page, + put Weekly Snapshot History link on 'Contributing' page. +* encoding/base64: add DecodeString and EncodeToString. +* encoding/binary: add a non-reflect fast path for Read, + add a non-reflect fast path for Write. +* encoding/hex: add hex dumping. +* encoding/line: delete package. Its functionality is now in bufio. +* filepath: Abs must always return a clean path (thanks Gustavo Niemeyer). +* fmt: fix bug in UnreadRune, + make %q work for integers, printing a quoted character literal, + return EOF when out of input in Scan*. +* gc: check parameter declarations in interface fields (thanks Anthony Martin), + disallow ... in type conversions (thanks Anthony Martin), + do not force heap allocation on referencing outer variable in a closure, + fix m[x], _ = y.(T), + implement new shift rules, + patch y.tab.c to fix build when using Bison 2.5, + relax assignability of method receivers (thanks Anthony Martin), + typecheck the whole tree before walking. +* go/scanner: don't allow "0x" and "0X" as integers (thanks Evan Shaw). +* gobuilder: fixes for windows (thanks Alex Brainman). +* godoc: basic setup for running godoc on local app engine emulator, + display advert for the package dashboard on package list page. +* goinstall: fixes for windows (thanks Alex Brainman), + more verbose logging with -v. +* gotest, pkg/exec: use bash to run shell scripts on windows (thanks Alex Brainman). +* http/spdy: redo interfaces, flesh out implementation & frame types (thanks William Chan). +* http: Transport hook to register non-http(s) protocols, + add client+server benchmark, + catch Handler goroutine panics, + fix Set-Cookie date parsing, + have client set Content-Length when possible, + let Transport use a custom net.Dial function, + propagate Set-Cookie in reverse proxy, + ServeFile shouldn't send Content-Length when Content-Encoding is set. +* image: add a SubImage method. +* image/gif: simplify blockReader.Read. +* image/png: fix encoding of images that don't start at (0, 0). +* io, net, http: sendfile support. +* io: add ByteScanner, RuneScanner interfaces. +* ld: add -w to disable dwarf, make errors obviously from dwarf. +* mail: new package. +* mime/multipart: misc code/doc fixes. +* misc/cgo: remove reference to 'destroy' function. +* misc/emacs: don't select the mark after gofmt (thanks Eric Eisner). +* misc/gophertool: Chrome extension to aid in Go development +* misc/vim: limit Fmt command to Go buffers (thanks Yasuhiro Matsumoto). +* net: if we stop polling, remove any pending events for the socket, + update IP multicast socket options (thanks Mikio Hara). +* os: Fix test to work on Solaris, + fix Readdir(0) on EOF, + fix Readdir, Readdirnames (thanks Yuval Pavel Zholkover), + fix os.MkdirAll with backslash path separator (thanks Yasuhiro Matsumoto), + handle OpenFile flag parameter properly on Windows (thanks Alex Brainman). +* path/filepath: remove string constants. +* pkg: spelling tweaks, I-Z (thanks Robert Hencke). +* quietgcc: fix typo, respect $TMPDIR. +* runtime: do not garbage collect windows callbacks (thanks Alex Brainman), + fix mmap error return on linux (thanks Dmitry Chestnykh), + reset GOMAXPROCS during tests, + save cdecl registers in Windows SEH handler (thanks Alexey Borzenkov). +* spec: be precise with the use of the informal ellipsis and the Go token, + clarify rules for shifts. +* strconv: add QuoteRune; analogous to Quote but for runes rather than strings. +* strings: implement UnreadByte, UnreadRune. +* sync: always wake up sleeping goroutines on Cond.Signal (thanks Gustavo Niemeyer). +* sync/atomic: fix check64. +* syscall: add ProcAttr field to pass an unescaped command line on windows (thanks Vincent Vanackere), + add routing messages support for Linux and BSD (thanks Mikio Hara). +* template: fixes and clean-ups (thanks Gustavo Niemeyer). +* time: fix Format bug: midnight/noon are 12AM/PM not 0AM/PM. +* unicode: make the tables smaller. +</pre> + +<h2 id="2011-05-22">2011-05-22</h2> + +<pre> +This release includes changes to the http package that will require changes to +client code. + +The finalURL return value of the Client.Get method has been removed. +This value is now accessible via the new Request field on http.Response. +For example, this code: + + res, finalURL, err := http.Get(...) + +should be rewritten as: + + res, err := http.Get(...) + if err != nil { + // ... + } + finalURL := res.Request.URL.String() + +Uses of http.Get that assign the finalURL value to _ can be rewritten +automatically with gofix. + +This release also includes an optimization to the append function that makes it +between 2 and 5 times faster in typical use cases. + +Other changes: +* 5a, 6a, 8a, cc: remove old environment variables. +* 5c, 5g: fix build with too-smart gcc. +* 5l, 8l: add ELF symbol table to binary. +* 5l: delete pre-ARMv4 instruction implementations, other fixes. +* 6l, 8l: emit windows dwarf sections like other platforms (thanks Alex Brainman). +* 6l: fix emit windows dwarf sections (thanks Wei Guangjing). +* 8g: fix conversion from float to uint64 (thanks Anthony Martin). +* Make.cmd: create TARGDIR if necessary (thanks Gustavo Niemeyer). +* asn1: add big support. +* big: add Int methods to act on numbered bits (thanks Roger Peppe), + better support for string conversions, + support %v and # modifier, better handling of unknown formats. +* cgi: export RequestFromMap (thanks Evan Shaw), + set Request.TLS and Request.RemoteAddr for children. +* cgo: use packed struct to fix Windows behavior. +* codereview: add release branch support, + fetch metadata using JSON API, not XML scraping, + handle 'null as missing field' in rietveld json. +* compress/lzw: silently drop implied codes that are too large. +* compress/zlib: actually use provided dictionary in NewWriterDict +* crypto/openpgp: add key generation support, + change PublicKey.Serialize to include the header. +* crypto/rand: add utility functions for number generation (thanks Anthony Martin). +* crypto/tls: export the verified chains. +* crypto/x509/crl: add package. +* crypto/x509: export raw SubjectPublicKeyInfo, + support DSA public keys in X.509 certs, + support parsing and verifying DSA signatures (thanks Jonathan Allie). +* doc/roadmap: put "App Engine support" under "Done". +* doc: add I/O 2011 talks to talks/, docs.html, and front page. +* effective go: explain about values/pointers in String() example, + update to new Open signature. +* exp/draw: fast paths for drawing a YCbCr or an NRGBA onto an RGBA. +* filepath: make EvalSymlinks work on Windows (thanks Alex Brainman). +* flag: allow distinct sets of flags. +* gc: fix type switch error message for invalid cases (thanks Lorenzo Stoakes), + fix unsafe.Sizeof, + preserve original expression for errors. +* go/ast, go/doc, godoc: consider struct fields and interface methods when filtering ASTs. +* go/ast: consider anonymous fields and set Incomplete bit when filtering ASTs, + properly maintain map of package global imports. +* go/doc, godoc: when filtering for godoc, don't remove elements of a declaration. +* go/parser: accept parenthesized receive operations in select statements, + always introduce an ast.Object when declaring an identifier. +* go/printer, gofmt: fix alignment of "=" in const/var declarations, + fix formatting of expression lists (missing blank). +* go/printer: added simple performance benchmark, + make tests follow syntactic restrictions, + more accurate comment for incomplete structs/interfaces, +* go/token: faster FileSet.Position implementation. +* go/types: type checker API + testing infrastructure. +* godoc: added -index flag to enable/disable search index, + if there is no search box, don't run the respective JS code. +* gofmt: update test.sh (exclude a file w/ incorrect syntax). +* html: parse empty, unquoted, and single-quoted attribute values. +* http/cgi: correctly set request Content-Type (thanks Evan Shaw), + pass down environment variables for IRIX and Solaris. +* http/pprof: fix POST reading bug. +* http/spdy: new incomplete package (thanks Ross Light). +* http: Client.Do should follow redirects for GET and HEAD, + add Header.Write method (thanks Evan Shaw), + add Request.SetBasicAuth method, + add Transport.ProxySelector, + add http.SetCookie(ResponseWriter, *Cookie), + don't Clean query string in relative redirects, + fix FormFile nil pointer dereference on missing multipart form, + fix racy test with a simpler version, + fix two Transport gzip+persist crashes, + include Host header in requests, + make HEAD client request follow redirects (thanks Eivind Uggedal). + update cookie doc to reference new RFC 6265, + write cookies according to RFC 6265 (thanks Christian Himpel). +* image/bmp: implement a BMP decoder. +* image/gif: new package provides a GIF decoder. +* image/jpeg: decode grayscale images, not just color images. + optimizations and tweaks. +* image/png: encode paletted images with alpha channel (thanks Dmitry Chestnykh), + speed up opaque RGBA encoding. +* image/tiff: implement a decoder (thanks Benny Siegert). +* image: add type-specific Set methods and use them when decoding PNG, + make AlphaColor.Set conform to usual signature (thanks Roger Peppe), + png & jpeg encoding benchmarks. +* ld: do not emit reference to dynamic library named "", + fix alignment of rodata section on Plan 9 (thanks Anthony Martin), + make ELF binaries with no shared library dependencies static binaries. +* make.bash: remove old bash version of gotest on Windows (thanks Alex Brainman). +* make: add nuke target for C commands and libs (thanks Anthony Martin). +* mime/multipart: add FileName accessor on Part, + add Writer, + return an error on Reader EOF, not (nil, nil). +* misc/cgo/test: run tests. +* misc/emacs: use UTF-8 when invoking gofmt as a subprocess (thanks Sameer Ajmani). +* misc/vim: new Vim indentation script. +* net, http: add and make use of IP address scope identification API (thanks Mikio Hara). +* net: default to 127.0.0.1, not localhost, in TestICMP, + don't crash on unexpected DNS SRV responses, + enable SO_REUSEPORT on BSD variants (thanks Mikio Hara), + protocol family adaptive address family selection (thanks Mikio Hara), + re-enable wildcard listening (thanks Mikio Hara), + sort records returned by LookupSRV (thanks Gary Burd). +* os: make Readdir & Readdirnames return os.EOF at end, + make Setenv update C environment variables. +* reflect: allow unexported key in Value.MapIndex. +* runtime, sync/atomic: fix arm cas. +* runtime: add newline to "finalizer already set" error (thanks Albert Strasheim), + handle out-of-threads on Linux gracefully (thanks Albert Strasheim), + fix function args not checked warning on ARM (thanks Dave Cheney), + make StackSystem part of StackGuard (thanks Alexey Borzenkov), + maybe fix Windows build broken by cgo setenv CL. +* spec: clarify semantics of integer division, + clarify semantics of range clause, + fix error in production syntax, + narrow syntax for expression and select statements, + newlines cannot be used inside a char or "" string literal, + restricted expressions may still be parenthesized. +* strings: make Reader.Read use copy instead of an explicit loop. +* syscall: add Windows file mapping functions and constants (thanks Evan Shaw), + add IPv6 scope zone ID support (thanks Mikio Hara), + add netlink support for linux/386, linux/amd64, linux/arm (thanks Mikio Hara), + add Sendfile, + adjust freebsd syscalls.master URL properly (thanks Mikio Hara), + change Overlapped.HEvent type, it is a handle (thanks Alex Brainman). +* syslog: fix skipping of net tests (thanks Gustavo Niemeyer). +* template: support string, int and float literals (thanks Gustavo Niemeyer). +* xml: fix reflect error. +</pre> + +<h2 id="2011-04-27">2011-04-27 (<a href="release.html#r57">base for r57</a>)</h2> + +<pre> +This release includes revisions to the reflect package to make it more +efficient, after the last weekly's major API update. If your code uses reflect +it may require further changes, not all of which can be made automatically by +gofix. For the full details of the change, see + http://codereview.appspot.com/4435042 +Also, the Typeof and NewValue functions have been renamed to TypeOf and ValueOf. + +Other changes: +* 5c: make alignment rules match 5g, just like 6c matches 6g. +* 8g, 8l: fix "set but not used" gcc error (thanks Fazlul Shahriar). +* all-qemu.bash: remove DISABLE_NET_TESTS. +* build: remove DISABLE_NET_TESTS. +* builder: build multiple targets in parallel. +* cgo: avoid "incompatible pointer type" warning (thanks Albert Strasheim). +* codereview: add 'hg undo' command, various other fixes. +* compress/flate: dictionary support. +* compress/zlib: add FDICT flag in Reader/Writer (thanks Ross Light). +* container/heap: fix circular dependency in test. +* crypto/openpgp: better handling of keyrings. +* crypto/rsa: support > 3 primes. +* crypto/tls: add server-side OCSP stapling support. +* crypto/x509: memorize chain building. +* crypto: move certificate verification into x509. +* dashboard: build most recent revision first. +* doc: mention make version in install.html. +* expvar: add Func for functions that return values that are JSON marshalable. +* fmt: decrease recursion depth in tests to permit them to run under gccgo, + tweak the doc for %U. +* gc: allow complex types to be receiver types (thanks Robert Hencke), + correct handling of unexported method names in embedded interfaces, + explain why invalid receiver types are invalid, + fix copy([]int, string) error message (thanks Quan Yong Zhai), + fix 'invalid recursive type' error (thanks Lorenzo Stoakes), + many bug fixes. +* go spec: attempt at clarifying language for "append", + for map types, mention indexing operations. +* go/types: update for export data format change. +* gob: fix handling of indirect receivers for GobDecoders, + fix trivial bug in map marshaling, + have errorf always prefix the message with "gob: ", + test case for indirection to large field, + use new Implements and AssignableTo methods in reflect, + when decoding a string, allocate a string, not a []byte. +* gobuilder: permit builders of the form goos-goarch-foo, + respect MAKEFLAGS if provided (thanks Dave Cheney). +* godoc: use "search" input type for search box (thanks Dmitry Chestnykh). +* gofix: add support for reflect rename. +* gofmt: add -d (diff) (thanks David Crawshaw), + don't crash when rewriting nil interfaces in AST, + exclude test case that doesn't compile w/o errors, + gofmt test harness bug fix. +* goinstall: support GOPATH; building and installing outside the Go tree, + support building executable commands. +* gopack: fix prefix bug, + preserve safe flag when not adding unsafe objects to archive. +* gotest: add timing, respect $GOARCH, + generate gofmt-compliant code. +* http/cgi: copy some PATH environment variables to child, + improve Location response handling, + pass some default environment variables. +* http/fcgi: new package (thanks Evan Shaw). +* http: add NewRequest helper, + add MultipartForm, ParseMultipartForm, and FormFile to Request, + be clear when failing to connect to a proxy, + bug fixes and new tests, + consume request bodies before replying, + don't quote Set-Cookie Domain and Path (thanks Petar Maymounkov), + fix IP confusion in TestServerTimeouts, + handler timeout support, + ServerConn, ClientConn: add real Close (thanks Petar Maymounkov), + make Client redirect policy configurable, + put a limit on POST size, + reverse proxy handler. +* image/jpeg: add an encoder, + decode to a YCbCr image instead of an RGBA image. +* ioutil: add Discard. +* json: keep track of error offset in SyntaxError. +* ld: defend against some broken object files, + do not emit empty dwarf pe sections (thanks Alex Brainman), + fix 6l -d on Mac, diagnose invalid use of -d, + fix Plan 9 symbol table (thanks Anthony Martin), + remove MachoLoad limit. +* make: prevent rm provoking 'text file busy' errors (thanks Lorenzo Stoakes). +* mime/multipart: add ReadForm for parsing multipart forms, + limit line length to prevent abuse. +* mime: RFC 2231 continuation / non-ASCII support, + bunch more tests, few minor parsing fixes. +* misc/goplay: fix Tab and Shift+Enter in Firefox (thanks Dmitry Chestnykh). +* net: disable one more external network test, + fix EAI_BADFLAGS error on freebsd (thanks Mikio Hara), + fix ParseIP (thanks Quan Yong Zhai), + fix dialgoogle_test.go (thanks Quan Yong Zhai), + try /etc/hosts before loading DNS config (thanks Dmitry Chestnykh), + use C library resolver on FreeBSD, Linux, OS X / amd64, 386. +* os/user: new package to look up users. +* os: Open with O_APPEND|O_CREATE to append on Windows (thanks Alex Brainman), + fix race in ReadAt/WriteAt on Windows (thanks Alex Brainman), + turn EPIPE exit into panic. +* rc/env.bash: fix to build on windows under msys (thanks Joe Poirier). +* reflect: allow Slice of arrays, + fix Copy of arrays (thanks Gustavo Niemeyer), + require package qualifiers to match during interface check, + add Type.Implements, Type.AssignableTo, Value.CallSlice, + make Set match Go. +* rpc: allow the first argument of a method to be a value rather than a pointer, + run benchmarks over HTTP as well as direct network connections. +* run.bash: remove redundant rebuilds. +* runtime/plan9: warning remediation for Plan 9 (thanks Lucio De Re), +* runtime: many bug fixes, + fix GOMAXPROCS vs garbage collection bug (thanks Dmitriy Vyukov), + fix mkversion to output valid path separators (thanks Peter Mundy), + more graceful out-of-memory crash, + require package qualifiers to match during interface check, + skip functions with no lines when building src line table, + turn "too many EPIPE" into real SIGPIPE. +* src/pkg: make package doc comments consistently start with "Package foo". +* syscall: Madvise and Mprotect for Linux (thanks Albert Strasheim), + Mlock, Munlock, Mlockall, Munlockall on Linux (thanks Albert Strasheim), + add BPF support for darwin/386, darwin/amd64 (thanks Mikio Hara), + correct Windows CreateProcess input parameters (thanks Alex Brainman), + fix Ftruncate under linux/arm5 (thanks Dave Cheney), + permit StartProcess to hide the executed program on windows (thanks Vincent Vanackere). +* test/bench: update timings; moving to new machine. +* time: support Irix 6 location for zoneinfo files. +* tutorial: modernize the definition and use of Open, + replace the forever loops with finite counts in sieve programs. +* websocket: include *http.Request in websocket.Conn. +* xml: Parser hook for non-UTF-8 charset converters. +</pre> + +<h2 id="2011-04-13">2011-04-13</h2> + +<pre> +weekly.2011-04-13 + +This weekly snapshot includes major changes to the reflect package and the +os.Open function. Code that uses reflect or os.Open will require updating, +which can be done mechanically using the gofix tool. + +The reflect package's Type and Value types have changed. Type is now an +interface that implements all the possible type methods. Instead of a type +switch on a reflect.Type t, switch on t.Kind(). Value is now a struct value +that implements all the possible value methods. Instead of a type switch on a +reflect.Value v, switch on v.Kind(). See the change for the full details: + http://code.google.com/p/go/source/detail?r=843855f3c026 + +The os package's Open function has been replaced by three functions: + OpenFile(name, flag, perm) // same as old Open + Open(name) // same as old Open(name, O_RDONLY, 0) + Create(name) // same as old Open(name, O_RDWR|O_TRUNC|O_CREAT, 0666) + +To update your code to use the new APIs, run "gofix path/to/code". Gofix can't +handle all situations perfectly, so read and test the changes it makes before +committing them. + +Other changes: +* archive/zip: add func OpenReader, type ReadCloser (thanks Dmitry Chestnykh). +* asn1: Implement correct marshaling of length octets (thanks Luit van Drongelen). +* big: don't crash when printing nil ints. +* bufio: add ReadLine, to replace encoding/line. +* build: make the build faster, quieter. +* codereview: automatically port old diffs forward, + drop Author: line on self-clpatch, + recognize code URL without trailing slash. +* crypto/block: remove deprecated package. +* crypto/des: new package implementating DES and TDEA (thanks Yasuhiro Matsumoto). +* crypto/ecdsa, crypto/rsa: use io.ReadFull to read from random source (thanks Dmitry Chestnykh). +* crypto/rsa: add 3-prime support, + add support for precomputing CRT values, + flip the CRT code over so that it matches PKCS#1. +* crypto/x509: expose complete DER data (thanks Mikkel Krautz). +* doc: new "Functions" codewalk (thanks John DeNero). +* doc/roadmap: add sections on tools, packages. +* fmt: allow %U for unsigned integers. +* gc: fixes and optimizations. +* go/printer, gofmt: use blank to separate import rename from import path. +* go/scanner: better TokenString output. +* go/types: new Go type hierarchy implementation for AST. +* godashboard: show packages at launchpad.net (thanks Gustavo Niemeyer). +* gofix: add -diff, various fixes and helpers. +* gotest: fix a bug in error handling, + fixes for [^.]_test file pattern (thanks Peter Mundy), + handle \r\n returned by gomake on Windows (thanks Alex Brainman). +* gotype: use go/types GcImporter. +* govet: make name-matching for printf etc. case-insensitive. +* http: allow override of Content-Type for ServeFile, + client gzip support, + do not listen on 0.0.0.0 during test, + flesh out server Expect handling + tests. +* image/ycbcr: new package. +* image: allow "?" wildcards when registering image formats. +* io: fixes for Read with n > 0, os.EOF (thanks Robert Hencke). +* ld: correct Plan 9 compiler warnings (thanks Lucio De Re), + ELF header function declarations (thanks Lucio De Re), + fix Mach-O X86_64_RELOC_SIGNED relocations (thanks Mikkel Krautz), + fix Mach-O bss bug (thanks Mikkel Krautz), + fix dwarf decoding of strings for struct's fieldnames (thanks Luuk van Dijk), + fixes and optimizations (25% faster). +* log: generalize getting and setting flags and prefix. +* misc/cgo/life: enable build and test on Windows (thanks Alex Brainman). +* misc/vim: add plugin with Fmt command (thanks Dmitry Chestnykh), + update type highlighting for new reflect package. +* net: disable multicast tests by default (thanks Dave Cheney), + sort records returned by LookupMX (thanks Corey Thomasson). +* openpgp: Fix improper := shadowing (thanks Gustavo Niemeyer). +* os: rename Open to OpenFile, add new Open, Create, + fix Readdir in Plan 9 (thanks Fazlul Shahriar). +* os/inotify: use _test for test files, not _obj. +* pkg/path: enable tests on Windows (thanks Alex Brainman). +* reflect: new Type and Value API. +* src/pkg/Makefile: trim per-directory make output except on failure. +* syscall: Add DT_* and MADV_* constants on Linux (thanks Albert Strasheim), + add Mmap, Munmap on Linux, FreeBSD, OS X, + fix StartProcess in Plan 9 (thanks Fazlul Shahriar), + fix Windows Signaled (thanks Alex Brainman). +* test/bench: enable build and test on Windows (thanks Alex Brainman). +</pre> + +<h2 id="2011-04-04">2011-04-04</h2> + +<pre> +This release includes changes to the net package. Your code will require +changes if it uses the Dial or LookupHost functions. + +The laddr argument has been removed from net.Dial, and the cname return value +has been removed from net.LookupHost. The new net.LookupCNAME function can be +used to find the canonical host for a given name. You can update your +networking code with gofix. + +The gotest shell script has been replaced by a Go program, making testing +significantly faster. + +Other changes: +* asn1: extensions needed for parsing Kerberos. +* bufio: Write and WriteString cleanup (thanks Evan Shaw). +* bytes, strings: simplify Join (thanks Evan Shaw). +* crypto/cipher: bad CTR IV length now triggers panic. +* crypto/tls: extend NPN support to the client, + added X509KeyPair function to parse a Certificate from memory. +* crypto/x509: parse Extended Key Usage extension (thanks Mikkel Krautz). +* debug/gosym: remove need for gotest to run preparatory commands. +* fmt: implement precision (length of input) values for %q: %.20q. +* go/parser: fix scoping for local type declarations (thanks Roger Peppe), + package name must not be the blank identifier. +* go/printer, gofmt: remove special case for multi-line raw strings. +* gopack: add P flag to remove prefix from filename information. +* gotest: add -test.timeout option, + replace the shell script with the compiled program written in go, + execute gomake properly on Windows (thanks Alex Brainman). +* gotry: move into its own directory, separate from gotest. +* gotype: support for more tests, added one new test. +* http: add Transport.MaxIdleConnsPerHost, + use upper case hex in URL escaping (thanks Matt Jones). +* httptest: add NewTLSServer. +* misc/kate: reorganize, remove closed() (thanks Evan Shaw). +* misc/notepadplus: support for notepad++ (thanks Anthony Starks). +* net: implement non-blocking connect (thanks Alexey Borzenkov). +* os: fix MkdirAll("/thisdoesnotexist") (thanks Albert Strasheim), + Plan 9 support (thanks Yuval Pavel Zholkover), + add a few missing Plan 9 errors (thanks Andrey Mirtchovski), + fix FileInfo.Name returned by Stat (thanks David Forsythe). +* path/filepath.Glob: add an error return, + don't drop known matches on error. +* path/filepath: add support for Plan 9 (thanks Andrey Mirtchovski). +* scanner: treat line comments like in Go. +* syscall: Plan 9 support (thanks Yuval Pavel Zholkover), + StartProcess Chroot and Credential (thanks Albert Strasheim), + add BPF support for freebsd/386, freebsd/amd64 (thanks Mikio Hara), + make [Raw]Syscall6 pass 6th arg on linux/386 (thanks Evan Shaw). +</pre> + +<h2 id="2011-03-28">2011-03-28</h2> + +<pre> +This weekly release includes improved support for testing. + +Memory and CPU profiling is now available via the gotest tool. Gotest will +produce memory and CPU profiling data when invoked with the -test.memprofile +and -test.cpuprofile flags. Run "godoc gotest" for details. + +We have also introduced a way for tests to run quickly when an exhaustive test +is unnecessary. Gotest's new -test.short flag in combination with the testing +package's new Short function allows you to write tests that can be run in +normal or "short" mode; short mode is now used by all.bash to reduce +installation time. +The Makefiles know about the flag - you can just run "make testshort". + +Other changes: +* .hgignore: Ignore all goinstalled packages (thanks Evan Shaw). +* build: add all-qemu.bash, handful of arm fixes, + add support for SWIG, and add two SWIG examples, + diagnose Ubuntu's buggy copy of gold, + handle broken awk in version.bash (thanks Dave Cheney), + reenable clean.bash without gomake (thanks Gustavo Niemeyer). +* cgo: fix index-out-of-bounds bug. +* codereview: permit CLs of the form weekly.DATE +* crypto/ecdsa: truncate hash values. +* crypto/openpgp: add DSA signature support. +* dashboard: remove old python/bash builder, update README. +* doc: explain release and weekly tags in install.html. +* exec: document dir option for Run (thanks Gustavo Niemeyer). +* flag: document Nflag function (thanks Fazlul Shahriar). +* gc: remove interim ... error which rejects valid code. +* go/ast: implemented NewPackage, + merge CaseClause and TypeCaseClause. +* go/parser: fix memory leak by making a copy of token literals, + resolve identifiers properly. +* go/printer, gofmt: avoid exponential layout algorithm, + gofmt: simplify struct formatting and respect line breaks. +* go/scanner: to interpret line comments with Windows filenames (thanks Alex Brainman). +* go/token: use array instead of map for token->string table. +* gob: optimizations to reduce allocations, + use pointers in bootstrapType so interfaces behave properly. +* gobuilder: recognize CLs of the form weekly.DATE. +* godefs: handle volatile. +* godoc: add -template flag to specify custom templates, + fix path problem for windows (thanks Yasuhiro Matsumoto). +* gofix: httpserver - rewrite rw.SetHeader to rw.Header.Set. +* gofmt: add profiling flag. +* gopprof: fix bug: do not rotate 180 degrees for large scrolls, + update list of memory allocation functions. +* gotest: fix gofmt issue in generated _testmain.go. +* http: add NewProxyClientConn, + avoid crash when asked for multiple file ranges, + don't chunk 304 responses, + export Transport, add keep-alive support. +* ld: return > 0 exit code on unsafe import. +* misc/bbedit: remove closed keyword (thanks Anthony Starks). +* misc/emacs: gofmt: don't clobber the current buffer on failure. +* misc/vim: remove 'closed' as a builtin function. +* net: add FileConn, FilePacketConn, FileListener (thanks Albert Strasheim), + don't force epoll/kqueue to wake up in order to add new events, + let OS-specific AddFD routine wake up polling thread, + use preallocated buffer for epoll and kqueue/kevent. +* path/filepath: add EvalSymlinks function, + fix TestEvalSymlinks when run under symlinked GOROOT. +* path: work for windows (thanks Yasuhiro Matsumoto). +* rpc: increase server_test timeout (thanks Gustavo Niemeyer), + optimizations to reduce allocations. +* runtime: fix darwin/amd64 thread VM footprint (thanks Alexey Borzenkov), + fix gdb support for goroutines, + more stack split fixes, + os-specific types and code for setitimer, + update defs.h for freebsd-386 (thanks Devon H. O'Dell). +* strings: Map: avoid allocation when string is unchanged. +* syscall: GetsockoptInt (thanks Albert Strasheim), + StartProcess fixes for windows (thanks Alex Brainman), + permit non-blocking syscalls, + rename from .sh to .pl, because these files are in Perl. +* test: enable tests using v, ok := <-ch syntax (thanks Robert Hencke). +* time: give a helpful message when we can't set the time zone for testing. + isolate syscall reference in sys.go. +</pre> + +<h2 id="2011-03-15">2011-03-15</h2> + +<pre> +This week's release introduces a new release tagging scheme. We intend to +continue with our weekly releases, but have renamed the existing tags from +"release" to "weekly". The "release" tag will now be applied to one hand-picked +stable release each month or two. + +The revision formerly tagged "release.2011-03-07.1" (now "weekly.2011-03-07.1") +has been nominated our first stable release, and has been given the tag +"release.r56". As we tag each stable release we will post an announcement to +the new golang-announce mailing list: + http://groups.google.com/group/golang-announce + +You can continue to keep your Go installation updated using "hg update +release", but now you should only need to update once we tag a new stable +release, which we will announce here. If you wish to stay at the leading edge, +you should switch to the weekly tag with "hg update weekly". + + +This weekly release includes significant changes to the language spec and the +http, os, and syscall packages. Your code may need to be changed. It also +introduces the new gofix tool. + +The closed function has been removed from the language. The syntax for channel +receives has been changed to return an optional second value, a boolean value +indicating whether the channel is closed. This code: + v := <-ch + if closed(ch) { + // channel is closed + } +should now be written as: + v, ok := <-ch + if !ok { + // channel is closed + } + +It is now illegal to declare unused labels, just as it is illegal to declare +unused local variables. + +The new gofix tool finds Go programs that use old APIs and rewrites them to use +newer ones. After you update to a new Go release, gofix helps make the +necessary changes to your programs. Gofix will handle the http, os, and syscall +package changes described below, and we will update the program to keep up with +future changes to the libraries. + +The Hijack and Flush methods have been removed from the http.ResponseWriter +interface and are accessible via the new http.Hijacker and http.Flusher +interfaces. The RemoteAddr and UsingTLS methods have been moved from +http.ResponseWriter to http.Request. + +The http.ResponseWriter interface's SetHeader method has been replaced by a +Header() method that returns the response's http.Header. Caller code needs to +change. This code: + rw.SetHeader("Content-Type", "text/plain") +should now be written as: + rw.Header().Set("Content-Type", "text/plain") +The os and syscall packages' StartProcess functions now take their final three +arguments as an *os.ProcAttr and *syscall.ProcAttr values, respectively. This +code: + os.StartProcess(bin, args, env, dir, fds) +should now be written as: + os.StartProcess(bin, args, &os.ProcAttr{Files: fds, Dir: dir, Env: env}) + +The gob package will now encode and decode values of types that implement the +gob.GobEncoder and gob.GobDecoder interfaces. This allows types with unexported +fields to transmit self-consistent descriptions; one instance is big.Int and +big.Rat. + +Other changes: +* 5l, 6l, 8l: reduce binary size about 40% by omitting symbols for type, string, go.string. +* 5l, 8l: output missing section symbols (thanks Anthony Martin). +* 6l, 8l: fix gdb crash. +* Make.cmd: also clean _test* (thanks Gustavo Niemeyer). +* big: implemented custom Gob(En/De)coder for Int type. +* build: remove duplicate dependency in Make.cmd (thanks Robert Hencke), + run gotest in misc/cgo/test. +* codereview.py: don't suggest change -d if user is not CL author (thanks Robert Hencke). +* compress/lzw: benchmark a range of input sizes. +* crypto/ecdsa: add package. +* crypto/elliptic: add the N value of each curve. +* crypto/openpgp: bug fixes and fix misnamed function. +* crypto/tls: fix compile error (thanks Dave Cheney). +* doc: Effective Go: some small cleanups, + update FAQ. hello, world is now 1.1MB, down from 1.8MB, + update codelab wiki to fix template.Execute argument order. +* flag: visit the flags in sorted order, for nicer messages. +* fmt: do not export EOF = -1. +* fmt: make ScanState.Token more general (thanks Roger Peppe). +* gc: diagnose unused labels, + fix handling of return values named _, + include all dependencies in export metadata, + make unsafe.Pointer its own kind of type, instead of an equivalent to *any. +* go/ast, go/parser: populate identifier scopes at parse time. +* go/ast: add FileSet parameter to ast.Print and ast.Fprint. +* go/parser: first constant in a constant declaration must have a value. +* gob: efficiency and reliability fixes. +* gofmt: remove -trace and -ast flags. +* goinstall: handle $(GOOS) and $(GOARCH) in filenames, + handle .c files with gc when cgo isn't used, and + handle .s files with gc (thanks Gustavo Niemeyer). +* gopack: omit time stamps, makes output deterministic. +* gotype: commandline tool to typecheck go programs. +* govet: handle '*' in print format strings. +* hash: new FNV-1a implementation (thanks Pascal S. de Kloe). +* http/cgi: child support (e.g. Go CGI under Apache). +* http: adapt Cookie code to follow IETF draft (thanks Petar Maymounkov), + add test for fixed HTTP/1.0 keep-alive issue, + don't hit external network in client_test.go, + fix transport crash when request URL is nil, + rename interface Transport to RoundTripper, + run tests even with DISABLE_NET_TESTS=1. +* httptest: default the Recorder status code to 200 on a Write. +* io/ioutil: clean-up of ReadAll and ReadFile. +* ioutil: add NopCloser. +* ld: preserve symbol sizes during data layout. +* lib9, libmach: Change GOOS references to GOHOSTOS (thanks Evan Shaw). +* libmach: correct string comparison to revive 6cov on darwin (thanks Dave Cheney). +* misc/vim: Add indent script for Vim (thanks Ross Light). +* net, os, syslog: fixes for Solaris support. +* net: don't loop to drain wakeup pipe. +* nm: document -S flag. +* openpgp: add PublicKey KeyId string accessors. +* rpc: optimizations, add benchmarks and memory profiling, + use httptest.Server for tests (thanks Robert Hencke). +* runtime: reduce lock contention via wakeup on scheduler unlock, + scheduler, cgo reorganization, + split non-debugging malloc interface out of debug.go into mem.go. +* spec: clarify return statement rules. +* strings: add IndexRune tests, ASCII fast path, + better benchmark names; add BenchmarkIndex. +* syscall: implement Mount and Unmount for linux, + implement Reboot for linux. +* time: fix Time.ZoneOffset documentation (thanks Peter Mundy). +* tls: move PeerCertificates to ConnectionState. +</pre> + +<h2 id="2011-03-07">2011-03-07 (<a href="release.html#r56">base for r56</a>)</h2> + +<pre> +This release includes changes to the reflect and path packages. +Code that uses reflect or path may need to be updated. + +The reflect package's Value.Addr method has been renamed to Value.UnsafeAddr. +Code that uses the Addr method will have to call UnsafeAddr instead. + +The path package has been split into two packages: path and path/filepath. +Package path manipulates slash-separated paths, regardless of operating system. +Package filepath implements the local operating system's native file paths. +OS-specific functioanlity in pacakge path, such as Walk, moved to filepath. + +Other changes: +* build: fixes and simplifications (thanks Dave Cheney), + move $GOBIN ahead of /bin, /usr/bin in build $PATH. +* bzip2: speed up decompression. +* cgo: fix dwarf type parsing (thanks Gustavo Niemeyer), + put temporary source files in _obj (thanks Roger Peppe), + fix bug involving 0-argument callbacks. +* compress/lzw: optimizations. +* doc: add FAQ about "implements", + add FAQ about large binaries , + add FAQ about stack vs heap allocation, + add internationalization to roadmap, + describe platform-specific conventions in code.html. +* fmt: allow recursive calls to Fscan etc (thanks Roger Peppe), + make %#p suppress leading 0x. +* gc, gopack: add some missing flags to the docs. +* gc: fix init of packages named main (thanks Gustavo Niemeyer), +* gob: make recursive map and slice types work, and other fixes. + tentative support for GobEncoder/GobDecoder interfaces. +* gobuilder: add -package flag to build external packages and -v for verbose. +* gofmt: exclude test file that is not legal Go. +* goinstall: protect against malicious filenames (thanks Roger Peppe). +* goyacc: provide -p flag to set prefix for names, documentation update. +* http: add cookie support (thanks Petar Maymounkov), + allow handlers to send non-chunked responses, + export ParseHTTPVersion, + expose Client's Transport, + use WriteProxy, + rename ClientTransport to Transport. +* http/cgi: new package. +* http/httptest: new package. +* image: add a decoding test for common file formats. +* io/ioutil: add TempDir. +* mime/multipart: Header changed from map to MIMEHeader +* path/filepath: new OS-specific path support (thanks Gustavo Niemeyer). +* reflect: add PtrTo, add Value.Addr (old Addr is now UnsafeAddr). +* runtime: use kernel-supplied compare-and-swap on linux/arm. +* spec: minor clarification of scope rule for functions. +* sync/atomic: new package to expose atomic operations. +* syscall: regenerate zerrors_freebsd_amd64.go (thanks Mikio Hara), + work around FreeBSD execve kernel bug (thanks Devon H. O'Dell). +* template: document the delimiters. +* testing: run GC before each benchmark run (thanks Roger Peppe). +* unsafe: fix the documentation. +* websocket: use httptest.Server for tests (thanks Robert Hencke). +* xml: permit nested directives (thanks Chris Dollin). +</pre> + +<h2 id="2011-02-24">2011-02-24</h2> + +<pre> +This release includes changes to the http package and a small language change. +Your code will require changes if it manipulates http Headers or omits the +condition in if statements. + +The new http.Header type replaces map[string]string in the Header and Trailer +fields of http.Request and http.Response. +A Header value can be manipulated via its Get, Set, Add, and Del methods. +See http://golang.org/pkg/http/#Header + +The condition is now mandatory in if statements. +Previously it would default to true, as in switch and for statements. +This code is now illegal: + if x := foo(); { + // code that is always executed + } +The same effect can be achieved like this: + if x := foo(); true { + // code + } +Or, in a simpler form: + { + x := foo() + // code + } + +Other changes: +* 6l: new -Hwindowsgui flag allows to build windows gui pe (thanks Alex Brainman), + pe fixes (thanks Wei Guangjing). +* 8l, 6l: allow for more os threads to be created on Windows (thanks Alex Brainman), +* build: reduce the use of subshells in recursive make, and + remove unused NaCl conditional from make.bash (thanks Dave Cheney). +* codereview: fix clpatch with empty diffs (thanks Gustavo Niemeyer). +* compress/bzip2: add package. +* compress/lzw: implement a decoder. +* crypto/openpgp: add package. +* crypto/rand: add read buffer to speed up small requests (thanks Albert Strasheim). +* crypto/rsa: left-pad OAEP results when needed. +* crypto/tls: make protocol negotiation failure fatal. +* fmt: stop giving characters to the Scan method of Scanner when we hit a newline in Scanln. +* gc: interface error message fixes, + make string const comparison unsigned (thanks Jeff R. Allen). +* go spec: minor clarification on channel types. +* go/ast, parser: condition in if statement is mandatory. +* gob: compute information about a user's type once. + protect against pure recursive types. +* godoc: accept symbolic links as path names provided to -path, + add robots.txt, log errors when reading filter files. +* html: tokenize HTML comments. +* http: add proxy support (thanks Yasuhiro Matsumoto), + implement with net/textproto (thanks Petar Maymounkov), + send full URL in proxy requests, + introduce start of Client and ClientTransport. +* image/png: support for more formats (thanks Mikael Tillenius). +* json: only use alphanumeric tags, + use base64 to encode []byte (thanks Roger Peppe). +* ld: detect stack overflow due to NOSPLIT, drop rpath, support weak symbols. +* misc/dashboard/builder: talk to hg with utf-8 encoding. +* misc/dashboard: notify golang-dev on build failure. +* net: *netFD.Read to return os.EOF on eof under windows (thanks Alex Brainman), + add IPv4 multicast to UDPConn (thanks Dave Cheney), + more accurate IPv4-in-IPv6 API test (thanks Mikio Hara), + reject invalid net:proto network names (thanks Olivier Antoine). +* netchan: allow use of arbitrary connections (thanks Roger Peppe). +* os: add ENODATA and ENOTCONN (thanks Albert Strasheim). +* reflect: add a couple of sentences explaining how Methods operate, + add a secret method to ArrayOrSliceType to ensure it's only implemented by arrays and slices, + add pointer word to CommonType (placeholder for future work). +* runtime-gdb.py: gdb pretty printer for go strings properly handles length. +* runtime: various bug fixes, more complete stack traces, + record $GOROOT_FINAL for runtime.GOROOT. +* spec: delete incorrect mention of selector working on pointer to interface type. +* sync: add Cond (thanks Gustavo Niemeyer). +* syscall: add MCL_* flags for mlockall (thanks Albert Strasheim), + implement chmod() for win32 (thanks Yasuhiro Matsumoto). +* test/bench: update timings for new GC. +* testing: rename cmdline flags to avoid conflicts (thanks Gustavo Niemeyer). +* textproto: introduce Header type (thanks Petar Maymounkov). +* websocket: use new interface to access Header. +</pre> + +<h2 id="2011-02-15">2011-02-15</h2> + +<pre> +This release includes changes to the io, os, and template packages. +You may need to update your code. + +The io.ReadByter and io.ReadRuner interface types have been renamed to +io.ByteReader and io.RuneReader respectively. + +The os package's ForkExec function has been superseded by the new StartProcess +function and an API built around the Process type: + http://golang.org/pkg/os/#Process + +The order of arguments to template.Execute has been reversed to be consistent +the notion of "destination first", as with io.Copy, fmt.Fprint, and others. + +Gotest now works for package main in directories using Make.cmd-based makefiles. + +The memory allocation runtime problems from the last release are not completely +fixed. The virtual memory exhaustion problems encountered by people using +ulimit -v have been fixed, but there remain known garbage collector problems +when using GOMAXPROCS > 1. + +Other changes: +* 5l: stopped generating 64-bit eor. +* 8l: more work on plan9 support (thanks Yuval Pavel Zholkover). +* archive/zip: handle files with data descriptors. +* arm: working peep-hole optimizer. +* asn1: marshal true as 255, not 1. +* buffer.go: minor optimization, expanded comment. +* build: drop syslog on DISABLE_NET_TESTS=1 (thanks Gustavo Niemeyer), + allow clean.bash to work on fresh checkout, + change "all tests pass" message to be more obvious, + fix spaces in GOROOT (thanks Christopher Nielsen). +* bytes: fix bug in buffer.ReadBytes (thanks Evan Shaw). +* 5g: better int64 code, + don't use MVN instruction. +* cgo: don't run cgo when not compiling (thanks Gustavo Niemeyer), + fix _cgo_run timestamp file order (thanks Gustavo Niemeyer), + fix handling of signed enumerations (thanks Gustavo Niemeyer), + os/arch dependent #cgo directives (thanks Gustavo Niemeyer), + rename internal f to avoid conflict with possible C global named f. +* codereview: fix hgpatch on windows (thanks Yasuhiro Matsumoto), + record repository, base revision, + use cmd.communicate (thanks Yasuhiro Matsumoto). +* container/ring: replace Iter() with Do(). +* crypto/cipher: add resync open to OCFB mode. +* crypto/openpgp/armor: bug fixes. +* crypto/openpgp/packet: new subpackage. +* crypto/tls: load a chain of certificates from a file, + select best cipher suite, not worst. +* crypto/x509: add support for name constraints. +* debug/pe: ImportedSymbols fixes (thanks Wei Guangjing). +* doc/code: update to reflect that package names need not be unique. +* doc/codelab/wiki: a bunch of fixes (thanks Andrey Mirtchovski). +* doc/install: update for new versions of Mercurial. +* encoding/line: fix line returned after EOF. +* flag: allow hexadecimal (0xFF) and octal (0377) input for integer flags. +* fmt.Scan: scan binary-exponent floating format, 2.4p-3, + hexadecimal (0xFF) and octal (0377) integers. +* fmt: document %%; also %b for floating point. +* gc, ld: detect stale or incompatible object files, + package name main no longer reserved. +* gc: correct receiver in method missing error (thanks Lorenzo Stoakes), + correct rounding of denormal constants (thanks Eoghan Sherry), + select receive bug fix. +* go/printer, gofmt: smarter handling of multi-line raw strings. +* go/printer: line comments must always end in a newline, + remove notion of "Styler", remove HTML mode. +* gob: allow Decode(nil) and have it just discard the next value. +* godoc: use IsAbs to test for absolute paths (fix for win32) (thanks Yasuhiro Matsumoto), + don't hide package lookup error if there's no command with the same name. +* gotest: enable unit tests for main programs. +* http: add Server type supporting timeouts, + add pipelining to ClientConn, ServerConn (thanks Petar Maymounkov), + handle unchunked, un-lengthed HTTP/1.1 responses. +* io: add RuneReader. +* json: correct Marshal documentation. +* netchan: graceful handling of closed connection (thanks Graham Miller). +* os: implement new Process API (thanks Alex Brainman). +* regexp tests: make some benchmarks more meaningful. +* regexp: add support for matching against text read from RuneReader interface. +* rpc: make more tolerant of errors, properly discard values (thanks Roger Peppe). +* runtime: detect failed thread creation on Windows, + faster allocator, garbage collector, + fix virtual memory exhaustion, + implemented windows console ctrl handler (SIGINT) (thanks Hector Chu), + more detailed panic traces, line number work, + improved Windows callback handling (thanks Hector Chu). +* spec: adjust notion of Assignability, + allow import of packages named main, + clarification re: method sets of newly declared pointer types, + fix a few typos (thanks Anthony Martin), + fix Typeof() return type (thanks Gustavo Niemeyer), + move to Unicode 6.0. +* sync: diagnose Unlock of unlocked Mutex, + new Waitgroup type (thanks Gustavo Niemeyer). +* syscall: add SetsockoptIpMreq (thanks Dave Cheney), + add sockaddr_dl, sysctl with routing message support for darwin, freebsd (thanks Mikio Hara), + do not use NULL for zero-length read, write, + implement windows version of Fsync (thanks Alex Brainman), + make ForkExec acquire the ForkLock under windows (thanks Hector Chu), + make windows API return errno instead of bool (thanks Alex Brainman), + remove obsolete socket IO control (thanks Mikio Hara). +* template: add simple formatter chaining (thanks Kyle Consalus), + allow a leading '*' to indirect through a pointer. +* testing: include elapsed time in test output +* windows: replace remaining __MINGW32__ instances with _WIN32 (thanks Joe Poirier). +</pre> + +<h2 id="2011-02-01">2011-02-01</h2> + +<pre> +This release includes significant changes to channel operations and minor +changes to the log package. Your code will require modification if it uses +channels in non-blocking communications or the log package's Exit functions. + +Non-blocking channel operations have been removed from the language. +The equivalent operations have always been possible using a select statement +with a default clause. If a default clause is present in a select, that clause +will execute (only) if no other is ready, which allows one to avoid blocking on +a communication. + +For example, the old non-blocking send operation, + + if ch <- v { + // sent + } else { + // not sent + } + +should be rewritten as, + + select { + case ch <- v: + // sent + default: + // not sent + } + +Similarly, this receive, + + v, ok := <-ch + if ok { + // received + } else { + // not received + } + +should be rewritten as, + + select { + case v := <-ch: + // received + default: + // not received + } + +This change is a prelude to redefining the 'comma-ok' syntax for a receive. +In a later release, a receive expression will return the received value and an +optional boolean indicating whether the channel has been closed. These changes +are being made in two stages to prevent this semantic change from silently +breaking code that uses 'comma-ok' with receives. +There are no plans to have a boolean expression form for sends. + +Sends to a closed channel will panic immediately. Previously, an unspecified +number of sends would fail silently before causing a panic. + +The log package's Exit, Exitf, and Exitln functions have been renamed Fatal, +Fatalf, and Fatalln respectively. This brings them in line with the naming of +the testing package. + +The port to the "tiny" operating system has been removed. It is unmaintained +and untested. It was a toy to show that Go can run on raw hardware and it +served its purpose. The source code will of course remain in the repository +history, so it could be brought back if needed later. + +This release also changes some of the internal structure of the memory +allocator in preparation for other garbage collector changes. +If you run into problems, please let us know. +There is one known issue that we are aware of but have not debugged yet: + http://code.google.com/p/go/issues/detail?id=1464&. + +Other changes in this release: +* 5l: document -F, force it on old ARMs (software floating point emulation) +* 6g: fix registerization of temporaries (thanks Eoghan Sherry), + fix uint64(uintptr(unsafe.Pointer(&x))). +* 6l: Relocate CMOV* instructions (thanks Gustavo Niemeyer), + windows/amd64 port (thanks Wei Guangjing). +* 8l: add PE dynexport, emit DWARF in Windows PE, and + code generation fixes (thanks Wei Guangjing). +* bufio: make Flush a no-op when the buffer is empty. +* bytes: Add Buffer.ReadBytes, Buffer.ReadString (thanks Evan Shaw). +* cc: mode to generate go-code for types and variables. +* cgo: define CGO_CFLAGS and CGO_LDFLAGS in Go files (thanks Gustavo Niemeyer), + windows/386 port (thanks Wei Guangjing). +* codereview: fix windows (thanks Hector Chu), + handle file patterns better, + more ASCII vs. Unicode nonsense. +* crypto/dsa: add support for DSA. +* crypto/openpgp: add s2k. +* crypto/rand: use defer to unlock mutex (thanks Anschel Schaffer-Cohen). +* crypto/rsa: correct docstring for SignPKCS1v15. +* crypto: add package, a common place to store identifiers for hash functions. +* doc/codelab/wiki: update to work with template changes, add to run.bash. +* doc/spec: clarify address operators. +* ebnflint: exit with non-zero status on error. +* encoding/base32: new package (thanks Miek Gieben). +* encoding/line: make it an io.Reader too. +* exec: use custom error for LookPath (thanks Gustavo Niemeyer). +* fmt/doc: define width and precision for strings. +* gc: clearer error for struct == struct, + fix send precedence, + handle invalid name in type switch, + special case code for single-op blocking and non-blocking selects. +* go/scanner: fix build (adjust scanner EOF linecount). +* gob: better debugging, commentary, + make nested interfaces work, + report an error when encoding a non-empty struct with no public fields. +* godoc: full text index for whitelisted non-Go files, + show line numbers for non-go files (bug fix). +* gofmt -r: match(...) arguments may be nil; add missing guards. +* govet: add Panic to the list of functions. +* http: add host patterns (thanks Jose Luis Vázquez González), + follow relative redirect in Get. +* json: handle capital floating point exponent (1E100) (thanks Pieter Droogendijk). +* ld: add -I option to set ELF interpreter, + more robust decoding of reflection type info in generating dwarf. +* lib9: update to Unicode 6.0.0. +* make.bash: stricter selinux test (don't complain unless it is enabled). +* misc/vim: Import/Drop commands (thanks Gustavo Niemeyer), + set 'syntax sync' to a large value (thanks Yasuhiro Matsumoto). +* net: fix race condition in test, + return cname in LookupHost. +* netchan: avoid race condition in test, + fixed documentation for import (thanks Anschel Schaffer-Cohen). +* os: add ETIMEDOUT (thanks Albert Strasheim). +* runtime: generate Go defs for C types, + implementation of callback functions for windows (thanks Alex Brainman), + make Walk web browser example work (thanks Hector Chu), + make select fairer, + prefer fixed stack allocator over general memory allocator, + simpler heap map, memory allocation. +* scanner: fix Position returned by Scan, Pos, + don't read ahead in Init. +* suffixarray: use binary search for both ends of Lookup (thanks Eric Eisner). +* syscall: add missing network interface constants (thanks Mikio Hara). +* template: treat map keys as zero, not non-existent (thanks Roger Peppe). +* time: allow cancelling of After events (thanks Roger Peppe), + support Solaris zoneinfo directory. +* token/position: added SetLinesForContent. +* unicode: update to unicode 6.0.0. +* unsafe: add missing case to doc for Pointer. +</pre> + +<h2 id="2011-01-20">2011-01-20</h2> + +<pre> +This release removes the float and complex types from the language. + +The default type for a floating point literal is now float64, and +the default type for a complex literal is now complex128. + +Existing code that uses float or complex must be rewritten to +use explicitly sized types. + +The two-argument constructor cmplx is now spelled complex. +</pre> + +<h2 id="2011-01-19">2011-01-19</h2> + +<pre> +The 5g (ARM) compiler now has registerization enabled. If you discover it +causes bugs, use 5g -N to disable the registerizer and please let us know. + +The xml package now allows the extraction of nested XML tags by specifying +struct tags of the form "parent>child". See the XML documentation for an +example: http://golang.org/pkg/xml/ + +* 5a, 5l, 6a, 6l, 8a, 8l: handle out of memory, large allocations (thanks Jeff R. Allen). +* 8l: pe changes (thanks Alex Brainman). +* arm: fixes and improvements. +* cc: fix vlong condition. +* cgo: add complex float, complex double (thanks Sebastien Binet), + in _cgo_main.c define all provided symbols as functions. +* codereview: don't mail change lists with no files (thanks Ryan Hitchman). +* crypto/cipher: add OFB mode. +* expvar: add Float. +* fmt: document %X of string, []byte. +* gc, runtime: make range on channel safe for multiple goroutines. +* gc: fix typed constant declarations (thanks Anthony Martin). +* go spec: adjust language for constant typing. +* go/scanner: Make Init take a *token.File instead of a *token.FileSet. +* godoc: bring back "indexing in progress" message, + don't double HTML-escape search result snippets, + enable qualified identifiers ("math.Sin") as query strings again, + peephole optimization for generated HTML, + remove tab before formatted section. +* gofmt, go/printer: do not insert extra line breaks where they may break the code. +* http: fix Content-Range and Content-Length in response (thanks Clement Skau), + fix scheme-relative URL parsing; add ParseRequestURL, + handle HEAD requests correctly, + support for relative URLs. +* math: handle denormalized numbers in Frexp, Ilogb, Ldexp, and Logb (thanks Eoghan Sherry). +* net, syscall: return source address in Recvmsg (thanks Albert Strasheim). +* net: add LookupAddr (thanks Kyle Lemons), + add unixpacket (thanks Albert Strasheim), + avoid nil dereference if /etc/services can't be opened (thanks Corey Thomasson), + implement windows timeout (thanks Wei Guangjing). +* netchan: do not block sends; implement flow control (thanks Roger Peppe). +* regexp: reject bare '?'. (thanks Ben Lynn) +* runtime/cgo: don't define crosscall2 in dummy _cgo_main.c. +* runtime/debug: new package for printing stack traces from a running goroutine. +* runtime: add per-pause gc stats, + fix arm reflect.call boundary case, + print signal information during panic. +* spec: specify that int and uint have the same size. +* syscall: correct WSTOPPED on OS X, + correct length of GNU/Linux abstract Unix domain sockaddr, + correct length of SockaddrUnix. +* tutorial: make stdin, stdout, stderr work on Windows. +* windows: implement exception handling (thanks Hector Chu). +</pre> + +<h2 id="2011-01-12">2011-01-12</h2> + +<pre> +The json, gob, and template packages have changed, and code that uses them +may need to be updated after this release. They will no longer read or write +unexported struct fields. When marshalling a struct with json or gob the +unexported fields will be silently ignored. Attempting to unmarshal json or +gob data into an unexported field will generate an error. Accessing an +unexported field from a template will cause the Execute function to return +an error. + +Godoc now supports regular expression full text search, and this +functionality is now available on golang.org. + +Other changes: +* arm: initial cut at arm optimizer. +* bytes.Buffer: Fix bug in UnreadByte. +* cgo: export unsafe.Pointer as void*, fix enum const conflict, + output alignment fix (thanks Gustavo Niemeyer). +* crypto/block: mark as deprecated. +* crypto/openpgp: add error and armor. +* crypto: add twofish package (thanks Berengar Lehr). +* doc/spec: remove Maxalign from spec. +* encoding/line: new package for reading lines from an io.Reader. +* go/ast: correct end position for Index and TypeAssert expressions. +* gob: make (en|dec)code(Ui|I)nt methods rather than functions. +* godefs: better handling of enums. +* gofmt: don't attempt certain illegal rewrites, + rewriter matches apply to expressions only. +* goinstall: preliminary support for cgo packages (thanks Gustavo Niemeyer). +* hg: add cgo/_cgo_* to .hgignore. +* http: fix text displayed in Redirect. +* ld: fix exported dynamic symbols on Mach-O, + permit a Mach-O symbol to be exported in the dynamic symbol table. +* log: add methods for exit and panic. +* net: use closesocket api instead of CloseHandle on Windows (thanks Alex Brainman). +* netchan: make fields exported for gob change. +* os: add Sync to *File, wraps syscall.Fsync. +* runtime/cgo: Add callbacks to support SWIG. +* runtime: Restore scheduler stack position if cgo callback panics. +* suffixarray: faster creation algorithm (thanks Eric Eisner). +* syscall: fix mksysnum_linux.sh (thanks Anthony Martin). +* time.NewTicker: panic for intervals <= 0. +* time: add AfterFunc to call a function after a duration (thanks Roger Peppe), + fix tick accuracy when using multiple Tickers (thanks Eoghan Sherry).</pre> + +<h2 id="2011-01-06">2011-01-06</h2> + +<pre> +This release includes several fixes and changes: + +* build: Make.pkg: use installed runtime.h for cgo. +* cgo: disallow use of C.errno. +* crypto/cipher: fix OCFB, + make NewCBCEncrypter return BlockMode. +* doc: 6l: fix documentation of -L flag, + add golanguage.ru to foreign-language doc list, + effective go: explain the effect of repanicking better, + update Effective Go for template API change, + update contribution guidelines to prefix the change description. +* encoding/binary: reject types with implementation-dependent sizes (thanks Patrick Gavlin). +* exp/evalsimple fix handling of slices like s[:2] (thanks Sebastien Binet). +* fmt: made format string handling more efficient, + normalize processing of format string. +* gc: return constant floats for parts of complex constants (thanks Anthony Martin), + rewrite complex /= to l = l / r (thanks Patrick Gavlin), + fix &^=. +* go/ast: provide complete node text range info. +* gob: generate a better error message in one confusing place. +* godoc: fix godoc -src (thanks Icarus Sparry). +* goinstall: add -clean flag (thanks Kyle Lemons), + add checkout concept (thanks Caine Tighe), + fix -u for bzr (thanks Gustavo Niemeyer). +* http: permit empty Reason-Phrase in response Status-Line. +* io: fix Copyn EOF handling. +* net: fix close of Listener (thanks Michael Hoisie). +* regexp: fix performance bug, make anchored searches fail fast, + fix prefix bug. +* runtime/cgo: fix stackguard on FreeBSD/amd64 (thanks Anthony Martin). +* strconv: atof: added 'E' as valid token for exponent (thanks Stefan Nilsson), + update ftoa comment for 'E' and 'G'. +* strings: fix description of FieldsFunc (thanks Roger Peppe). +* syscall: correct Linux Splice definition, + make Access second argument consistently uint32. +</pre> + +<h2 id="2010-12-22">2010-12-22</h2> + +<pre> +A small release this week. The most significant change is that some +outstanding cgo issues were resolved. + +* cgo: handle references to symbols in shared libraries. +* crypto/elliptic: add serialisation and key pair generation. +* crypto/hmac: add HMAC-SHA256 (thanks Anthony Martin). +* crypto/tls: add ECDHE support ("Elliptic Curve Diffie Hellman Ephemeral"), + add support code for generating handshake scripts for testing. +* darwin, freebsd: ignore write failure (during print, panic). +* exp/draw: remove Border function. +* expvar: quote StringFunc output, same as String output. +* hash/crc64: fix typo in Sum. +* ld: allow relocations pointing at ELF .bss symbols, ignore stab symbols. +* misc/cgo/life: fix, add to build. +* regexp: add HasMeta, HasOperator, and String methods to Regexp. +* suffixarray: implemented FindAllIndex regexp search. +* test/bench: update numbers for regex-dna after speedup to regexp. +* time: explain the formats a little better. +</pre> + +<h2 id="2010-12-15">2010-12-15</h2> + +<pre> +Package crypto/cipher has been started, to replace crypto/block. +As part of the changes, rc4.Cipher's XORKeyStream method signature has changed from + XORKeyStream(buf []byte) +to + XORKeyStream(dst, src []byte) +to implement the cipher.Stream interface. If you use crypto/block, you'll need +to switch to crypto/cipher once it is complete. + +Package smtp's StartTLS now takes a *tls.Config argument. + +Package reflect's ArrayCopy has been renamed to Copy. There are new functions +Append and AppendSlice. + +The print/println bootstrapping functions now write to standard error. +To write to standard output, use fmt.Print[ln]. + +A new tool, govet, has been added to the Go distribution. Govet is a static +checker for Go programs. At the moment, and for the forseeable future, +it only checks arguments to print calls. + +The cgo tool for writing Go bindings for C code has changed so that it no +longer uses stub .so files (like cgo_stdio.so). Cgo-based packages using the +standard Makefiles should build without any changes. Any alternate build +mechanisms will need to be updated. + +The C and Go compilers (6g, 6c, 8g, 8c, 5g, 5c) now align structs according to +the maximum alignment of the fields they contain; previously they aligned +structs to word boundaries. This may break non-cgo-based code that attempts to +mix C and Go. + +NaCl support has been removed. The recent linker changes broke NaCl support +a month ago, and there are no known users of it. +If necessary, the NaCl code can be recovered from the repository history. + +* 5g/8g, 8l, ld, prof: fix output of 32-bit values (thanks Eoghan Sherry). +* [68]l and runtime: GDB support for interfaces and goroutines. +* 6l, 8l: support for linking ELF and Mach-O .o files. +* all: simplify two-variable ranges with unused second variable (thanks Ryan Hitchman). +* arm: updated soft float support. +* codereview: keep quiet when not in use (thanks Eoghan Sherry). +* compress/flate: implement Flush, equivalent to zlib's Z_SYNC_FLUSH. +* crypto/tls: use rand.Reader in cert generation example (thanks Anthony Martin). +* dashboard: fix project tag filter. +* debug/elf, debug/macho: add ImportedLibraries, ImportedSymbols. +* doc/go_mem: goroutine exit is not special. +* event.go: another print glitch from gocheck. +* gc: bug fixes, + syntax error for incomplete chan type (thanks Ryan Hitchman). +* go/ast: fix ast.Walk. +* gob: document the byte count used in the encoding of values, + fix bug sending zero-length top-level slices and maps, + Register should use the original type, not the indirected one. +* godashboard: support submitting projects with non-ascii names (thanks Ryan Hitchman) +* godefs: guard against structs with pad fields +* godoc: added textual search, to enable use -fulltext flag. +* gofmt: simplify "x, _ = range y" to "x = range y". +* gopack: allow ELF/Mach-O objects in .a files without clearing allobj. +* go/token,scanner: fix comments so godoc aligns properly. +* govet: on error continue to the next file (thanks Christopher Wedgwood). +* html: improved parsing. +* http: ServeFile handles Range header for partial requests. +* json: check for invalid UTF-8. +* ld: allow .o files with no symbols, + reading of ELF object files, + reading of Mach-O object files. +* math: change float64 bias constant from 1022 to 1023 (thanks Eoghan Sherry), + rename the MinFloat constant to SmallestNonzeroFloat. +* nm: silently ignore .o files in .a files. +* os: fix test of RemoveAll. +* os/inotify: new package (thanks Balazs Lecz). +* os: make MkdirAll work with symlinks (thanks Ryan Hitchman). +* regexp: speed up by about 30%; also simplify code for brackets. +* runtime/linux/386: set FPU to 64-bit precision. +* runtime: remove paranoid mapping at 0. +* suffixarray: add Bytes function. +* syscall: add network interface constants for linux/386, linux/amd64 (thanks Mikio Hara). +* syscall/windows: restrict access rights param of OpenProcess(), + remove \r and \n from error messages (thanks Alex Brainman). +* test/bench: fixes to timing.sh (thanks Anthony Martin). +* time: fix bug in Ticker: shutdown using channel rather than memory. +* token/position: provide FileSet.File, provide files iterator. +* xml: disallow invalid Unicode code points (thanks Nigel Kerr). +</pre> + +<h2 id="2010-12-08">2010-12-08</h2> + +<pre> +This release includes some package changes. If you use the crypto/tls or +go/parser packages your code may require changes. + +The crypto/tls package's Dial function now takes an additional *Config +argument. Most uses will pass nil to get the same default behavior as before. +See the documentation for details: + http://golang.org/pkg/crypto/tls/#Config + http://golang.org/pkg/crypto/tls/#Dial + +The go/parser package's ParseFile function now takes a *token.FileSet as its +first argument. This is a pointer to a data structure used to store +position information. If you don't care about position information you +can pass "token.NewFileSet()". See the documentation for details: + http://golang.org/pkg/go/parser/#ParseFile + +This release also splits the patent grant text out of the LICENSE file into a +separate PATENTS file and changes it to be more like the WebM grant. +These clarifications were made at the request of the Fedora project. + +Other changes: +* [68]l: generate debug info for builtin structured types, prettyprinting in gdb. +* 8l: add dynimport to import table in Windows PE (thanks Wei Guangjing). +* 8l, runtime: fix Plan 9 386 build (thanks Yuval Pavel Zholkover). +* all: fix broken calls to Printf etc. +* bufio: make Reader.Read implement io.Reader semantics (thanks Roger Peppe). +* build: allow archiver to be specified by HOST_AR (thanks Albert Strasheim). +* bytes: add Buffer.UnreadRune, Buffer.UnreadByte (thanks Roger Peppe). +* crypto/tls: fix build of certificate generation example (thanks Christian Himpel). +* doc/install: describe GOHOSTOS and GOHOSTARCH. +* errchk: accept multiple source files (thanks Eoghan Sherry). +* exec.LookPath: return os.PathError instad of os.ENOENT (thanks Michael Hoisie).. +* flag: fix format error in boolean error report, + handle multiple calls to flag.Parse. +* fmt: add %U format for standard Unicode representation of code point values. +* gc: fix method offsets of anonymous interfaces (thanks Eoghan Sherry), + skip undefined symbols in import . (thanks Eoghan Sherry). +* go/scanner: remove Tokenize - was only used in tests +* gobuilder: add buildroot command-line flag (thanks Devon H. O'Dell). +* html: unescape numeric entities (thanks Ryan Hitchman). +* http: Add EncodeQuery, helper for constructing query strings. +* ld: fix dwarf decoding of 64-bit reflect values (thanks Eoghan Sherry). +* math: improve accuracy of Exp2 (thanks Eoghan Sherry). +* runtime: add Goroutines (thanks Keith Rarick). +* sync: small naming fix for armv5 (thanks Dean Prichard). +* syscall, net: Add Recvmsg and Sendmsg on Linux (thanks Albert Strasheim). +* time: make After use fewer goroutines and host processes (thanks Roger Peppe). +</pre> + +<h2 id="2010-12-02">2010-12-02</h2> + +<pre> +Several package changes in this release may require you to update your code if +you use the bytes, template, or utf8 packages. In all cases, any outdated code +will fail to compile rather than behave erroneously. + +The bytes package has changed. Its Add and AddByte functions have been removed, +as their functionality is provided by the recently-introduced built-in function +"append". Any code that uses them will need to be changed: +s = bytes.Add(s, b) -> s = append(s, b...) +s = bytes.AddByte(b, c) -> s = append(s, b) +s = bytes.Add(nil, c) -> append([]byte(nil), c) + +The template package has changed. Your code will need to be updated if it calls +the HTMLFormatter or StringFormatter functions, or implements its own formatter +functions. The function signature for formatter types has changed to: + func(wr io.Writer, formatter string, data ...interface{}) +to allow multiple arguments to the formatter. No templates will need updating. +See the change for examples: + http://code.google.com/p/go/source/detail?r=2c2be793120e + +The template change permits the implementation of multi-word variable +instantiation for formatters. Before one could say + {field} +or + {field|formatter} +Now one can also say + {field1 field2 field3} +or + {field1 field2 field3|formatter} +and the fields are passed as successive arguments to the formatter, +by analogy to fmt.Print. + +The utf8 package has changed. The order of EncodeRune's arguments has been +reversed to satisfy the convention of "destination first". +Any code that uses EncodeRune will need to be updated. + +Other changes: +* [68]l: correct dwarf location for globals and ranges for arrays. +* big: fix (*Rat) SetFrac64(a, b) when b < 0 (thanks Eoghan Sherry). +* compress/flate: fix typo in comment (thanks Mathieu Lonjaret). +* crypto/elliptic: use a Jacobian transform for better performance. +* doc/code.html: fix reference to "gomake build" (thanks Anschel Schaffer-Cohen). +* doc/roadmap: update gdb status. +* doc/spec: fixed some omissions and type errors. +* doc: some typo fixes (thanks Peter Mundy). +* exp/eval: build fix for parser.ParseFile API change (thanks Anschel Schaffer-Cohen). +* fmt: Scan accepts Inf and NaN, + allow "% X" as well as "% x". +* go/printer: preserve newlines in func parameter lists (thanks Jamie Gennis). +* http: consume request body before next request. +* log: ensure writes are atomic (thanks Roger Peppe). +* path: Windows support for Split (thanks Benny Siegert). +* runtime: fix SysFree to really free memory on Windows (thanks Alex Brainman), + parallel definitions in Go for all C structs. +* sort: avoid overflow in pivot calculation, + reduced stack depth to lg(n) in quickSort (thanks Stefan Nilsson). +* strconv: Atof on Infs and NaNs. +</pre> + +<h2 id="2010-11-23">2010-11-23</h2> + +<pre> +This release includes a backwards-incompatible package change to the +sort.Search function (introduced in the last release). +See the change for details and examples of how you might change your code: + http://code.google.com/p/go/source/detail?r=102866c369 + +* build: automatically #define _64BIT in 6c. +* cgo: print required space after parameter name in wrapper function. +* crypto/cipher: new package to replace crypto/block (thanks Adam Langley). +* crypto/elliptic: new package, implements elliptic curves over prime fields (thanks Adam Langley). +* crypto/x509: policy OID support and fixes (thanks Adam Langley). +* doc: add link to codewalks, + fix recover() documentation (thanks Anschel Schaffer-Cohen), + explain how to write Makefiles for commands. +* exec: enable more tests on windows (thanks Alex Brainman). +* gc: adjustable hash code in typecheck of composite literals + (thanks to vskrap, Andrey Mirtchovski, and Eoghan Sherry). +* gc: better error message for bad type in channel send (thanks Anthony Martin). +* godoc: bug fix in relativePath, + compute search index for all file systems under godoc's observation, + use correct time stamp to indicate accuracy of search result. +* index/suffixarray: use sort.Search. +* net: add ReadFrom and WriteTo windows version (thanks Wei Guangjing). +* reflect: remove unnecessary casts in Get methods. +* rpc: add RegisterName to allow override of default type name. +* runtime: free memory allocated by windows CommandLineToArgv (thanks Alex Brainman). +* sort: simplify Search (thanks Roger Peppe). +* strings: add LastIndexAny (thanks Benny Siegert). +</pre> + +<h2 id="2010-11-10">2010-11-10</h2> + +<pre> +The birthday release includes a new Search capability inside the sort package. +It takes an unusual but very general and easy-to-use approach to searching +arbitrary indexable sorted data. See the documentation for details: + http://golang.org/pkg/sort/#Search + +The ARM port now uses the hardware floating point unit (VFP). It still has a +few bugs, mostly around conversions between unsigned integer and floating-point +values, but it's stabilizing. + +In addition, there have been many smaller fixes and updates: + +* 6l: generate dwarf variable names with disambiguating suffix. +* container/list: make Remove return Value of removed element. + makes it easier to remove first or last item. +* crypto: add cast5 (default PGP cipher), + switch block cipher methods to be destination first. +* crypto/tls: use pool building for certificate checking +* go/ast: change embedded token.Position fields to named fields + (preparation for a different position representation) +* net: provide public access to file descriptors (thanks Keith Rarick) +* os: add Expand function to evaluate environment variables. +* path: add Glob (thanks Benny Siegert) +* runtime: memequal optimization (thanks Graham Miller) + prefix all external symbols with "runtime·" to avoid + conflicts linking with external C libraries. +</pre> + +<h2 id="2010-11-02">2010-11-02</h2> + +<pre> +This release includes a language change: the new built-in function, append. +Append makes growing slices much simpler. See the spec for details: + http://golang.org/doc/go_spec.html#Appending_and_copying_slices + +Other changes: +* 8l: pe generation fixes (thanks Alex Brainman). +* doc: Effective Go: append and a few words about "..." args. +* build: fiddle with make variables. +* codereview: fix sync and download in Python 2.7 (thanks Fazlul Shahriar). +* debug/pe, cgo: add windows support (thanks Wei Guangjing). +* go/ast: add Inspect function for easy AST inspection w/o a visitor. +* go/printer: do not remove parens around composite literals starting with + a type name in control clauses. +* go/scanner: bug fixes, revisions, and more tests. +* gob: several fixes and documentation updates. +* godoc: bug fix (bug introduced with revision 3ee58453e961). +* gotest: print empty benchmark list in a way that gofmt will leave alone. +* http server: correctly respond with 304 NotModified (thanks Michael Hoisie). +* kate: update list of builtins (thanks Evan Shaw). +* libutf: update to Unicode 5.2.0 to match pkg/unicode (thanks Anthony Martin). +* misc/bbedit: update list of builtins (thanks Anthony Starks). +* misc/vim: update list of builtins. +* mkrunetype: install a Makefile and tweak it slightly so it can be built. +* netchan: fix locking bug. +* pidigits: minor improvements (thanks Evan Shaw). +* rpc: fix client deadlock bug. +* src: use append where appropriate (often instead of vector). +* strings: add Contains helper function (thanks Brad Fitzpatrick). +* syscall: SIO constants for Linux (thanks Albert Strasheim), + Stat(path) on windows (thanks Alex Brainman). +* test/ken/convert.go: add conversion torture test. +* testing: add Benchmark (thanks Roger Peppe). +</pre> + +<h2 id="2010-10-27">2010-10-27</h2> + +<pre> +*** This release changes the encoding used by package gob. + If you store gobs on disk, see below. *** + +The ARM port (5g) now passes all tests. The optimizer is not yet enabled, and +floating point arithmetic is performed entirely in software. Work is underway +to address both of these deficiencies. + +The syntax for arrays, slices, and maps of composite literals has been +simplified. Within a composite literal of array, slice, or map type, elements +that are themselves composite literals may elide the type if it is identical to +the outer literal's element type. For example, these expressions: + [][]int{[]int{1, 2, 3}, []int{4, 5}} + map[string]Point{"x": Point{1.5, -3.5}, "y": Point{0, 0}} +can be simplified to: + [][]int{{1, 2, 3}, {4, 5}} + map[string]Point{"x": {1.5, -3.5}, "y": {0, 0}} +Gofmt can make these simplifications mechanically when invoked with the +new -s flag. + +The built-in copy function can now copy bytes from a string value to a []byte. +Code like this (for []byte b and string s): + for i := 0; i < len(s); i++ { + b[i] = s[i] + } +can be rewritten as: + copy(b, s) + +The gob package can now encode and decode interface values containing types +registered ahead of time with the new Register function. These changes required +a backwards-incompatible change to the wire format. Data written with the old +version of the package will not be readable with the new one, and vice versa. +(Steps were made in this change to make sure this doesn't happen again.) +We don't know of anyone using gobs to create permanent data, but if you do this +and need help converting, please let us know, and do not update to this release +yet. We will help you convert your data. + +Other changes: +* 5g, 6g, 8g: generate code for string index instead of calling function. +* 5l, 6l, 8l: introduce sub-symbols. +* 6l/8l: global and local variables and type info. +* Make.inc: delete unnecessary -fno-inline flag to quietgcc. +* arm: precise float64 software floating point, bug fixes. +* big: arm assembly, faster software mulWW, divWW. +* build: only print "You need to add foo to PATH" when needed. +* container/list: fix Remove bug and use pointer to self as identifier. +* doc: show page title in browser title bar, + update roadmap. +* encoding/binary: give LittleEndian, BigEndian specific types. +* go/parser: consume auto-inserted semi when calling ParseExpr(). +* gobuilder: pass GOHOSTOS and GOHOSTARCH to build, + write build and benchmarking logs to disk. +* goinstall: display helpful message when encountering a cgo package, + fix test for multiple package names (thanks Fazlul Shahriar). +* gotest: generate correct gofmt-formatted _testmain.go. +* image/png: speed up paletted encoding ~25% (thanks Brad Fitzpatrick). +* misc: update python scripts to specify python2 as python3 is now "python". +* net: fix comment on Dial to mention unix/unixgram. +* rpc: expose Server type to allow multiple RPC Server instances. +* runtime: print unknown types in panic. +* spec: append built-in (not yet implemented). +* src: gofmt -s -w src misc. + update code to use copy-from-string. +* test/bench: update numbers. +* websocket: fix short Read. +</pre> + +<h2 id="2010-10-20">2010-10-20</h2> + +<pre> +This release removes the log package's deprecated functions. +Code that has not been updated to use the new interface will break. +See the previous release notes for details: + http://golang.org/doc/devel/release.html#2010-10-13 + +Also included are major improvements to the linker. It is now faster, +uses less memory, and more parallelizable (but not yet parallel). + +The nntp package has been removed from the standard library. +Its new home is the nntp-go project at Google Code: + http://code.google.com/p/nntp-go +You can install it with goinstall: + goinstall nntp-go.googlecode.com/hg/nntp +And import it in your code like so: + import "nntp-go.googlecode.com/hg/nntp" + +Other changes: +* 6g: avoid too-large immediate constants. +* 8l, runtime: initial support for Plan 9 (thanks Yuval Pavel Zholkover). +* 6l, 8l: more improvements on exporting debug information (DWARF). +* arm: code gen fixes. Most tests now pass, except for floating point code. +* big: add random number generation (thanks Florian Uekermann). +* gc: keep track of real actual type of identifiers, + report that shift must be unsigned integer, + select receive with implicit conversion. +* goplay: fix to run under windows (thanks Yasuhiro Matsumoto). +* http: do not close connection after sending HTTP/1.0 request. +* netchan: add new method Hangup to terminate transmission on a channel. +* os: change TestForkExec so it can run on windows (thanks Yasuhiro Matsumoto). +* runtime: don't let select split stack. +* syscall/arm: correct 64-bit system call arguments. +</pre> + +<h2 id="2010-10-13">2010-10-13</h2> + +<pre> +This release includes changes to the log package, the removal of exp/iterable, +two new tools (gotry and goplay), one small language change, and many other +changes and fixes. If you use the log or iterable packages, you need to make +changes to your code. + +The log package has changed. Loggers now have only one output, and output to +standard error by default. The names have also changed, although the old names +are still supported. They will be deleted in the next release, though, so it +would be good to update now if you can. For most purposes all you need to do +is make these substitutions: + log.Stderr -> log.Println or log.Print + log.Stderrf -> log.Printf + log.Crash -> log.Panicln or log.Panic + log.Crashf -> log.Panicf + log.Exit -> log.Exitln or log.Exit + log.Exitf -> log.Exitf (no change) +Calls to log.New() must drop the second argument. +Also, custom loggers with exit or panic properties will need to be reworked. +For full details, see the change description: + http://code.google.com/p/go/source/detail?r=d8a3c7563d + +The language change is that uses of pointers to interface values no longer +automatically dereference the pointer. A pointer to an interface value is more +often a beginner's bug than correct code. + +The package exp/iterable has been removed. It was an interesting experiment, +but it encourages writing inefficient code and has outlived its utility. + +The new tools: +* gotry: an exercise in reflection and an unusual tool. Run 'gotry' for details. +* goplay: a stand-alone version of the Go Playground. See misc/goplay. + +Other changes: +* 6l: Mach-O fixes, and fix to work with OS X nm/otool (thanks Jim McGrath). +* [568]a: correct line numbers for statements. +* arm: code generation and runtime fixes, + adjust recover for new reflect.call, + enable 6 more tests after net fix. +* big: fix panic and round correctly in Rat.FloatString (thanks Anthony Martin). +* build: Make.cmd: remove $(OFILES) (thanks Eric Clark), + Make.pkg: remove .so before installing new one, + add GOHOSTOS and GOHOSTARCH environment variables. +* crypto/tls: better error messages for certificate issues, + make SetReadTimeout work. +* doc: add Sydney University video, + add The Expressiveness of Go talk. +* exp/draw/x11: support X11 vendors other than "The X.Org Foundation". +* expvar: add (*Int).Set (thanks Sam Thorogood). +* fmt: add Errorf helper function, + allow %d on []byte. +* gc: O(1) string comparison when lengths differ, + various bug fixes. +* http: return the correct error if a header line is too long. +* image: add image.Tiled type, the Go equivalent of Plan 9's repl bit. +* ld: be less picky about bad line number info. +* misc/cgo/life: fix for new slice rules (thanks Graham Miller). +* net: allow _ in DNS names. +* netchan: export before import when testing, and + zero out request to ensure correct gob decoding. (thanks Roger Peppe). +* os: make tests work on windows (thanks Alex Brainman). +* runtime: bug fix: serialize mcache allocation, + correct iteration of large map values, + faster strequal, memequal (thanks Graham Miller), + fix argument dump in traceback, + fix tiny build. +* smtp: new package (thanks Evan Shaw). +* syscall: add sockaddr_ll support for linux/386, linux/amd64 (thanks Mikio Hara), + add ucred structure for SCM_CREDENTIALS over UNIX sockets. (thanks Albert Strasheim). +* syscall: implement WaitStatus and Wait4() for windows (thanks Wei Guangjing). +* time: add After. +* websocket: enable tests on windows (thanks Alex Brainman). +</pre> + +<h2 id="2010-09-29">2010-09-29</h2> + +<pre> +This release includes some minor language changes and some significant package +changes. You may need to change your code if you use ...T parameters or the +http package. + +The semantics and syntax of forwarding ...T parameters have changed. + func message(f string, s ...interface{}) { fmt.Printf(f, s) } +Here, s has type []interface{} and contains the parameters passed to message. +Before this language change, the compiler recognized when a function call +passed a ... parameter to another ... parameter of the same type, and just +passed it as though it was a list of arguments. But this meant that you +couldn't control whether to pass the slice as a single argument and you +couldn't pass a regular slice as a ... parameter, which can be handy. This +change gives you that control at the cost of a few characters in the call. +If you want the promotion to ..., append ... to the argument: + func message(f string, s ...interface{}) { fmt.Printf(f, s...) } +Without the ..., s would be passed to Printf as a single argument of type +[]interface{}. The bad news is you might need to fix up some of your code, +but the compiler will detect the situation and warn you. + +Also, the http.Handler and http.HandlerFunc types have changed. Where http +handler functions previously accepted an *http.Conn, they now take an interface +type http.ResponseWriter. ResponseWriter implements the same methods as *Conn, +so in most cases the only change required will be changing the type signature +of your handler function's first parameter. See: + http://golang.org/pkg/http/#Handler + +The utf8 package has a new type, String, that provides efficient indexing +into utf8 strings by rune (previously an expensive conversion to []int +was required). See: + http://golang.org/pkg/utf8/#String + +The compiler will now automatically insert a semicolon at the end of a file if +one is not found. This effect of this is that Go source files are no longer +required to have a trailing newline. + +Other changes: +* 6prof: more accurate usage message. +* archive/zip: new package for reading Zip files. +* arm: fix code generation, 10 more package tests pass. +* asn1: make interface consistent with json. +* bufio.UnreadRune: fix bug at EOF. +* build: clear custom variables like GREP_OPTIONS, + silence warnings generated by ubuntu gcc, + use full path when compiling libraries. +* bytes, strings: change lastIndexFunc to use DecodeLastRune (thanks Roger Peppe). +* doc: add to and consolidate non-english doc references, + consolidate FAQs into a single file, go_faq.html, + updates for new http interface. +* fmt/Printf: document and tweak error messages produced for bad formats. +* gc: allow select case expr = <-c, + eliminate duplicates in method table, + fix reflect table method receiver, + improve error message for x \= 0. +* go/scanner: treat EOF like a newline for purposes of semicolon insertion. +* gofmt: stability improvements. +* gotest: leave _testmain.go for "make clean" to clean up. +* http: correct escaping of different parts of URL, + support HTTP/1.0 Keep-Alive. +* json: do not write to unexported fields. +* libcgo: don't build for NaCl, + set g, m in thread local storage for windows 386 (thanks Wei Guangjing). +* math: Fix off-by-one error in Ilogb and Logb. (thanks Charles L. Dorian). +* misc/dashboard/builder: remove build files after benchmarking. +* nacl: update instructions for new SDK. +* net: enable v4-over-v6 on ip sockets, + fix crash in DialIP. +* os: check for valid arguments in windows Readdir (thanks Peter Mundy). +* runtime: add mmap of null page just in case, + correct stats in SysFree, + fix unwindstack crash. +* syscall: add IPPROTO_IPV6 and IPV6_V6ONLY const to fix nacl and windows build, + add inotify on Linux (thanks Balazs Lecz), + fix socketpair in syscall_bsd, + fix windows value of IPV6_V6ONLY (thanks Alex Brainman), + implement windows version of Utimes (thanks Alex Brainman), + make mkall.sh work for nacl. +* test: Add test that causes incorrect error from gccgo. +* utf8: add DecodeLastRune and DecodeLastRuneInString (thanks Roger Peppe). +* xml: Allow entities inside CDATA tags (thanks Dan Sinclair). +</pre> + +<h2 id="2010-09-22">2010-09-22</h2> + +<pre> +This release includes new package functionality, and many bug fixes and changes. +It also improves support for the arm and nacl platforms. + +* 5l: avoid fixed buffers in list. +* 6l, 8l: clean up ELF code, fix NaCl. +* 6l/8l: emit DWARF frame info. +* Make.inc: make GOOS detection work on windows (thanks Alex Brainman). +* build: fixes for native arn build, + make all.bash run on Ubuntu ARM. +* cgo: bug fixes, + show preamble gcc errors (thanks Eric Clark). +* crypto/x509, crypto/tls: improve root matching and observe CA flag. +* crypto: Fix certificate validation. +* doc: variable-width layout. +* env.bash: fix building in directory with spaces in the path (thanks Alex Brainman). +* exp/4s, exp/nacl/av: sync to recent exp/draw changes. +* exp/draw/x11: mouse location is a signed integer. +* exp/nacl/av: update color to max out at 1<<16-1 instead of 1<<32-1. +* fmt: support '*' for width or precision (thanks Anthony Martin). +* gc: improvements to static initialization, + make sure path names are canonical. +* gob: make robust when decoding a struct with non-struct data. +* gobuilder: add -cmd for user-specified build command, + add -rev= flag to build specific revision and exit, + fix bug that caused old revisions to be rebuilt. +* godoc: change default filter file name to "", + don't use quadratic algorithm to filter paths, + show "Last update" info for directory listings. +* http: new redirect test, + URLEscape now escapes all reserved characters as per the RFC. +* nacl: fix zero-length writes. +* net/dict: parse response correctly (thanks Fazlul Shahriar). +* netchan: add a cross-connect test, + handle closing of channels, + provide a method (Importer.Errors()) to recover protocol errors. +* os: make Open() O_APPEND flag work on windows (thanks Alex Brainman), + make RemoveAll() work on windows (thanks Alex Brainman). +* pkg/Makefile: disable netchan test to fix windows build (thanks Alex Brainman). +* regexp: delete Iter methods. +* runtime: better panic for send to nil channel. +* strings: fix minor bug in LastIndexFunc (thanks Roger Peppe). +* suffixarray: a package for creating suffixarray-based indexes. +* syscall: Use vsyscall for syscall.Gettimeofday and .Time on linux amd64. +* test: fix NaCl build. +* windows: fix netchan test by using 127.0.0.1. +</pre> + +<h2 id="2010-09-15">2010-09-15</h2> + +<pre> +This release includes a language change: the lower bound of a subslice may +now be omitted, in which case the value will default to 0. +For example, s[0:10] may now be written as s[:10], and s[0:] as s[:]. + +The release also includes important bug fixes for the ARM architecture, +as well as the following fixes and changes: + +* 5g: register allocation bugs +* 6c, 8c: show line numbers in -S output +* 6g, 6l, 8g, 8l: move read-only data to text segment +* 6l, 8l: make etext accurate; introduce rodata, erodata. +* arm: fix build bugs. + make libcgo build during OS X cross-compile + remove reference to deleted file syntax/slice.go + use the correct stat syscalls + work around reg allocator bug in 5g +* bufio: add UnreadRune. +* build: avoid bad environment interactions + fix build for tiny + generate, clean .exe files on Windows (thanks Joe Poirier) + test for _WIN32, not _MINGW32 (thanks Joe Poirier) + work with GNU Make 3.82 (thanks Jukka-Pekka Kekkonen) +* cgo: add typedef for uintptr in generated headers + silence warning for C call returning const pointer +* codereview: convert email address to lower case before checking CONTRIBUTORS +* crypto/tls: don't return an error from Close() +* doc/tutorial: update for slice changes. +* exec: separate LookPath implementations for unix/windows (thanks Joe Poirier) +* exp/draw/x11: allow clean shutdown when the user closes the window. +* exp/draw: clip destination rectangle to the image bounds. + fast path for drawing overlapping image.RGBAs. + fix double-counting of pt.Min for the src and mask points. + reintroduce the MouseEvent.Nsec timestamp. + rename Context to Window, and add a Close method. +* exp/debug: preliminary support for 'copy' function (thanks Sebastien Binet) +* fmt.Fscan: use UnreadRune to preserve data across calls. +* gc: better printing of named constants, func literals in errors + many bug fixes + fix line number printing with //line directives + fix symbol table generation on windows (thanks Alex Brainman) + implement comparison rule from spec change 33abb649cb63 + implement new slice spec (thanks Scott Lawrence) + make string x + y + z + ... + w efficient + more accurate line numbers for ATEXT + remove &[10]int -> []int conversion +* go-mode.el: fix highlighting for 'chan' type (thanks Scott Lawrence) +* godoc: better support for directory trees for user-supplied paths + use correct delay time (bug fix) +* gofmt, go/printer: update internal estimated position correctly +* goinstall: warn when package name starts with http:// (thanks Scott Lawrence) +* http: check https certificate against host name + do not cache CanonicalHeaderKey (thanks Jukka-Pekka Kekkonen) +* image: change a ColorImage's minimum point from (0, 0) to (-1e9, -1e9). + introduce Intersect and Union rectangle methods. +* ld: handle quoted spaces in package path (thanks Dan Sinclair) +* libcgo: fix NaCl build. +* libmach: fix build on arm host + fix new thread race with Linux +* math: make portable Tan(Pi/2) return NaN +* misc/dashboard/builder: gobuilder, a continuous build client +* net: disable tests for functions not available on windows (thanks Alex Brainman) +* netchan: make -1 unlimited, as advertised. +* os, exec: rename argv0 to name +* path: add IsAbs (thanks Ivan Krasin) +* runtime: fix bug in tracebacks + fix crash trace on amd64 + fix windows build (thanks Alex Brainman) + use manual stack for garbage collection +* spec: add examples for slices with omitted index expressions. + allow omission of low slice bound (thanks Scott Lawrence) +* syscall: fix windows Gettimeofday (thanks Alex Brainman) +* test(arm): disable zerodivide.go because compilation fails. +* test(windows): disable tests that cause the build to fail (thanks Joe Poirier) +* test/garbage/parser: sync with recent parser changes +* test: Add test for //line + Make gccgo believe that the variables can change. + Recognize gccgo error messages. + Reduce race conditions in chan/nonblock.go. + Run garbage collector before testing malloc numbers. +* websocket: Add support for secure WebSockets (thanks Jukka-Pekka Kekkonen) +* windows: disable unimplemented tests (thanks Joe Poirier) +</pre> + +<h2 id="2010-09-06">2010-09-06</h2> + +<pre> +This release includes the syntactic modernization of more than 100 files in /test, +and these additions, changes, and fixes: +* 6l/8l: emit DWARF in macho. +* 8g: use FCHS, not FMUL, for minus float. +* 8l: emit DWARF in ELF, + suppress emitting DWARF in Windows PE (thanks Alex Brainman). +* big: added RatString, some simplifications. +* build: create bin and pkg directories as needed; drop from hg, + delete Make.386 Make.amd64 Make.arm (obsoleted by Make.inc), + fix cgo with -j2, + let pkg/Makefile coordinate building of Go commands, + never use quietgcc in Make.pkg, + remove more references to GOBIN and GOROOT (thanks Christian Himpel). +* codereview: Fix uploading for Mercurial 1.6.3 (thanks Evan Shaw), + consistent indent, cut dead code, + fix hang on standard hg commands, + print status when tasks take longer than 30 seconds, + really disable codereview when not available, + upload files in parallel (5x improvement on large CLs). +* crypto/hmac: make Sum idempotent (thanks Jukka-Pekka Kekkonen). +* doc: add links to more German docs, + add round-robin flag to io2010 balance example, + fix a bug in the example in Constants subsection (thanks James Fysh), + various changes for validating HTML (thanks Scott Lawrence). +* fmt: delete erroneous sentence about return value for Sprint*. +* gc: appease bison version running on FreeBSD builder, + fix spurious syntax error. +* go/doc: use correct escaper for URL. +* go/printer: align ImportPaths in ImportDecls (thanks Scott Lawrence). +* go/typechecker: 2nd step towards augmenting AST with full type information. +* gofmt: permit omission of first index in slice expression. +* goinstall: added -a flag to mean "all remote packages" (thanks Scott Lawrence), + assume go binaries are in path (following new convention), + use https for Google Code checkouts. +* gotest: allow make test of cgo packages (without make install). +* http: add Date to server, Last-Modified and If-Modified-Since to file server, + add PostForm function to post url-encoded key/value data, + obscure passwords in return value of URL.String (thanks Scott Lawrence). +* image: introduce Config type and DecodeConfig function. +* libcgo: update Makefile to use Make.inc. +* list: update comment to state that the zero value is ready to use. +* math: amd64 version of Sincos (thanks Charles L. Dorian). +* misc/bash: add *.go completion for gofmt (thanks Scott Lawrence). +* misc/emacs: make _ a word symbol (thanks Scott Lawrence). +* misc: add zsh completion (using compctl), + syntax highlighting for Fraise.app (OS X) (thanks Vincent Ambo). +* net/textproto: Handle multi-line responses (thanks Evan Shaw). +* net: add LookupMX (thanks Corey Thomasson). +* netchan: Fix race condition in test, + rather than 0, make -1 mean infinite (a la strings.Split et al), + use acknowledgements on export send. + new methods Sync and Drain for clean teardown. +* regexp: interpret all Go characer escapes \a \b \f \n \r \t \v. +* rpc: fix bug that caused private methods to attempt to be registered. +* runtime: Correct commonType.kind values to match compiler, + add GOOS, GOARCH; fix FuncLine, + special case copy, equal for one-word interface values (thanks Kyle Consalus). +* scanner: fix incorrect reporting of error in Next (thanks Kyle Consalus). +* spec: clarify that arrays must be addressable to be sliceable. +* template: fix space handling around actions. +* test/solitaire: an exercise in backtracking and string conversions. +* test: Recognize gccgo error messages and other fixes. +* time: do not crash in String on nil Time. +* tutorial: regenerate HTML to pick up change to progs/file.go. +* websocket: fix missing Sec-WebSocket-Protocol on server response (thanks Jukka-Pekka Kekkonen). +</pre> + +<h2 id="2010-08-25">2010-08-25</h2> + +<pre> +This release includes changes to the build system that will likely require you +to make changes to your environment variables and Makefiles. + +All environment variables are now optional: + - $GOOS and $GOARCH are now optional; their values should now be inferred + automatically by the build system, + - $GOROOT is now optional, but if you choose not to set it you must run + 'gomake' instead of 'make' or 'gmake' when developing Go programs + using the conventional Makefiles, + - $GOBIN remains optional and now defaults to $GOROOT/bin; + if you wish to use this new default, make sure it is in your $PATH + and that you have removed the existing binaries from $HOME/bin. + +As a result of these changes, the Go Makefiles have changed. If your Makefiles +inherit from the Go Makefiles, you must change this line: + include ../../Make.$(GOARCH) +to this: + include ../../Make.inc + +This release also removes the deprecated functions in regexp and the +once package. Any code that still uses them will break. +See the notes from the last release for details: + http://golang.org/doc/devel/release.html#2010-08-11 + +Other changes: +* 6g: better registerization for slices, strings, interface values +* 6l: line number information in DWARF format +* build: $GOBIN defaults to $GOROOT/bin, + no required environment variables +* cgo: add C.GoStringN (thanks Eric Clark). +* codereview: fix issues with leading tabs in CL descriptions, + do not send "Abandoned" mail if the CL has not been mailed. +* crypto/ocsp: add missing Makefile. +* crypto/tls: client certificate support (thanks Mikkel Krautz). +* doc: update gccgo information for recent changes. + fix errors in Effective Go. +* fmt/print: give %p priority, analogous to %T, + honor Formatter in Print, Println. +* gc: fix parenthesization check. +* go/ast: facility for printing AST nodes, + first step towards augmenting AST with full type information. +* go/printer: do not modify tabwriter.Escape'd text. +* gofmt: do not modify multi-line string literals, + print AST nodes by setting -ast flag. +* http: fix typo in http.Request documentation (thanks Scott Lawrence) + parse query string always, not just in GET +* image/png: support 16-bit color. +* io: ReadAtLeast now errors if min > len(buf). +* jsonrpc: use `error: null` for success, not `error: ""`. +* libmach: implement register fetch for 32-bit x86 kernel. +* net: make IPv6 String method standards-compliant (thanks Mikio Hara). +* os: FileInfo.Permission() now returns uint32 (thanks Scott Lawrence), + implement env using native Windows API (thanks Alex Brainman). +* reflect: allow PtrValue.PointTo(nil). +* runtime: correct line numbers for .goc files, + fix another stack split bug, + fix freebsd/386 mmap. +* syscall: regenerate syscall/z* files for linux/386, linux/amd64, linux/arm. +* tabwriter: Introduce a new flag StripEscape. +* template: fix handling of space around actions, + vars preceded by white space parse correctly (thanks Roger Peppe). +* test: add test case that crashes gccgo. +* time: parse no longer requires minutes for time zone (thanks Jan H. Hosang) +* yacc: fix bounds check in error recovery. +</pre> + +<h2 id="2010-08-11">2010-08-11</h2> + +<pre> +This release introduces some package changes. You may need to change your +code if you use the once, regexp, image, or exp/draw packages. + +The type Once has been added to the sync package. The new sync.Once will +supersede the functionality provided by the once package. We intend to remove +the once package after this release. See: + http://golang.org/pkg/sync/#Once +All instances of once in the standard library have been replaced with +sync.Once. Reviewing these changes may help you modify your existing code. +The relevant changeset: + http://code.google.com/p/go/source/detail?r=fa2c43595119 + +A new set of methods has been added to the regular expression package, regexp. +These provide a uniformly named approach to discovering the matches of an +expression within a piece of text; see the package documentation for details: + http://golang.org/pkg/regexp/ +These new methods will, in a later release, replace the old methods for +matching substrings. The following methods are deprecated: + Execute (use FindSubmatchIndex) + ExecuteString (use FindStringSubmatchIndex) + MatchStrings(use FindStringSubmatch) + MatchSlices (use FindSubmatch) + AllMatches (use FindAll; note that n<0 means 'all matches'; was n<=0) + AllMatchesString (use FindAllString; note that n<0 means 'all matches'; was n<=0) +(Plus there are ten new methods you didn't know you wanted.) +Please update your code to use the new routines before the next release. + +An image.Image now has a Bounds rectangle, where previously it ranged +from (0, 0) to (Width, Height). Loops that previously looked like: + for y := 0; y < img.Height(); y++ { + for x := 0; x < img.Width(); x++ { + // Do something with img.At(x, y) + } + } +should instead be: + b := img.Bounds() + for y := b.Min.Y; y < b.Max.Y; y++ { + for x := b.Min.X; x < b.Max.X; x++ { + // Do something with img.At(x, y) + } + } +The Point and Rectangle types have also moved from exp/draw to image. + +Other changes: +* arm: bugfixes and syscall (thanks Kai Backman). +* asn1: fix incorrect encoding of signed integers (thanks Nicholas Waples). +* big: fixes to bitwise functions (thanks Evan Shaw). +* bytes: add IndexRune, FieldsFunc and To*Special (thanks Christian Himpel). +* encoding/binary: add complex (thanks Roger Peppe). +* exp/iterable: add UintArray (thanks Anschel Schaffer-Cohen). +* godoc: report Status 404 if a pkg or file is not found. +* gofmt: better reporting for unexpected semicolon errors. +* html: new package, an HTML tokenizer. +* image: change image representation from slice-of-slices to linear buffer, + introduce Decode and RegisterFormat, + introduce Transparent and Opaque, + replace Width and Height by Bounds, add the Point and Rect types. +* libbio: fix Bprint to address 6g issues with large data structures. +* math: fix amd64 Hypot (thanks Charles L. Dorian). +* net/textproto: new package, with example net/dict. +* os: fix ForkExec() handling of envv == nil (thanks Alex Brainman). +* png: grayscale support (thanks Mathieu Lonjaret). +* regexp: document that backslashes are the escape character. +* rpc: catch errors from ReadResponseBody. +* runtime: memory free fix (thanks Alex Brainman). +* template: add ParseFile method to template.Template. +* test/peano: use directly recursive type def. +</pre> + +<h2 id="2010-08-04">2010-08-04</h2> + +<pre> +This release includes a change to os.Open (and co.). The file permission +argument has been changed to a uint32. Your code may require changes - a simple +conversion operation at most. + +Other changes: +* amd64: use segment memory for thread-local storage. +* arm: add gdb support to android launcher script, + bugfixes (stack clobbering, indices), + disable another flaky test, + remove old qemu dependency from gotest. +* bufio: introduce Peek. +* bytes: added test case for explode with blank string (thanks Scott Lawrence). +* cgo: correct multiple return value function invocations (thanks Christian Himpel). +* crypto/x509: unwrap Subject Key Identifier (thanks Adam Langley). +* gc: index bounds tests and other fixes. +* gofmt/go/parser: strengthen syntax checks. +* goinstall: check for error from exec.*Cmd.Wait() (thanks Alex Brainman). +* image/png: use image-specific methods for checking opacity. +* image: introduce Gray and Gray16 types, + remove the named colors except for Black and White. +* json: object members must have a value (thanks Anthony Martin). +* misc/vim: highlight misspelled words only in comments (thanks Christian Himpel). +* os: Null device (thanks Peter Mundy). +* runtime: do not fall through in SIGBUS/SIGSEGV. +* strings: fix Split("", "", -1) (thanks Scott Lawrence). +* syscall: make go errors not clash with windows errors (thanks Alex Brainman). +* test/run: diff old new, +* websocket: correct challenge response (thanks Tarmigan Casebolt), + fix bug involving spaces in header keys (thanks Bill Neubauer). +</pre> + +<h2 id="2010-07-29">2010-07-29</h2> + +<pre> +* 5g: more soft float support and several bugfixes. +* asn1: Enumerated, Flag and GeneralizedTime support. +* build: clean.bash to check that GOOS and GOARCH are set. +* bytes: add IndexFunc and LastIndexFunc (thanks Fazlul Shahriar), + add Title. +* cgo: If CC is set in environment, use it rather than "gcc", + use new command line syntax: -- separates cgo flags from gcc flags. +* codereview: avoid crash if no config, + don't run gofmt with an empty file list, + make 'hg submit' work with Mercurial 1.6. +* crypto/ocsp: add package to parse OCSP responses. +* crypto/tls: add client-side SNI support and PeerCertificates. +* exp/bignum: delete package - functionality subsumed by package big. +* fmt.Print: fix bug in placement of spaces introduced when ...T went in. +* fmt.Scanf: handle trailing spaces. +* gc: fix smaller-than-pointer-sized receivers in interfaces, + floating point precision/normalization fixes, + graceful exit on seg fault, + import dot shadowing bug, + many fixes including better handling of invalid input, + print error detail about failure to open import. +* gccgo_install.html: add description of the port to RTEMS (thanks Vinu Rajashekhar). +* gobs: fix bug in singleton arrays. +* godoc: display synopses for all packages that have some kind of documentation.. +* gofmt: fix some linebreak issues. +* http: add https client support (thanks Fazlul Shahriar), + write body when content length unknown (thanks James Whitehead). +* io: MultiReader and MultiWriter (thanks Brad Fitzpatrick), + fix another race condition in Pipes. +* ld: many fixes including better handling of invalid input. +* libmach: correct handling of .5 files with D_REGREG addresses. +* linux/386: use Xen-friendly ELF TLS instruction sequence. +* mime: add AddExtensionType (thanks Yuusei Kuwana). +* misc/vim: syntax file recognizes constants like 1e9 (thanks Petar Maymounkov). +* net: TCPConn.SetNoDelay, back by popular demand. +* net(windows): fix crashing Read/Write when passed empty slice on (thanks Alex Brainman), + implement LookupHost/Port/SRV (thanks Wei Guangjing), + properly handle EOF in (*netFD).Read() (thanks Alex Brainman). +* runtime: fix bug introduced in revision 4a01b8d28570 (thanks Alex Brainman), + rename cgo2c, *.cgo to goc2c, *.goc (thanks Peter Mundy). +* scanner: better comment. +* strings: add Title. +* syscall: add ForkExec, Syscall12 on Windows (thanks Daniel Theophanes), + improve windows errno handling (thanks Alex Brainman). +* syscall(windows): fix FormatMessage (thanks Peter Mundy), + implement Pipe() (thanks Wei Guangjing). +* time: fix parsing of minutes in time zones. +* utf16(windows): fix cyclic dependency when testing (thanks Peter Mundy). +</pre> + +<h2 id="2010-07-14">2010-07-14</h2> + +<pre> +This release includes a package change. In container/vector, the Iter method +has been removed from the Vector, IntVector, and StringVector types. Also, the +Data method has been renamed to Copy to better express its actual behavior. +Now that Vector is just a slice, any for loops ranging over v.Iter() or +v.Data() can be changed to range over v instead. + +Other changes: +* big: Improvements to Rat.SetString (thanks Evan Shaw), + add sign, abs, Rat.IsInt. +* cgo: various bug fixes. +* codereview: Fix for Mercurial >= 1.6 (thanks Evan Shaw). +* crypto/rand: add Windows implementation (thanks Peter Mundy). +* crypto/tls: make HTTPS servers easier, + add client OCSP stapling support. +* exp/eval: converted from bignum to big (thanks Evan Shaw). +* gc: implement new len spec, range bug fix, optimization. +* go/parser: require that '...' parameters are followed by a type. +* http: fix ParseURL to handle //relative_path properly. +* io: fix SectionReader Seek to seek backwards (thanks Peter Mundy). +* json: Add HTMLEscape (thanks Micah Stetson). +* ld: bug fixes. +* math: amd64 version of log (thanks Charles L. Dorian). +* mime/multipart: new package to parse multipart MIME messages + and HTTP multipart/form-data support. +* os: use TempFile with default TempDir for test files (thanks Peter Mundy). +* runtime/tiny: add docs for additional VMs, fix build (thanks Markus Duft). +* runtime: better error for send/recv on nil channel. +* spec: clarification of channel close(), + lock down some details about channels and select, + restrict when len(x) is constant, + specify len/cap for nil slices, maps, and channels. +* windows: append .exe to binary names (thanks Joe Poirier). +</pre> + +<h2 id="2010-07-01">2010-07-01</h2> + +<pre> +This release includes some package changes that may require changes to +client code. + +The Split function in the bytes and strings packages has been changed. +The count argument, which limits the size of the return, previously treated +zero as unbounded. It now treats 0 as 0, and will return an empty slice. +To request unbounded results, use -1 (or some other negative value). +The new Replace functions in bytes and strings share this behavior. +This may require you change your existing code. + +The gob package now allows the transmission of non-struct values at the +top-level. As a result, the rpc and netchan packages have fewer restrictions +on the types they can handle. For example, netchan can now share a chan int. + +The release also includes a Code Walk: "Share Memory By Communicating". +It describes an idiomatic Go program that uses goroutines and channels: + http://golang.org/doc/codewalk/sharemem/ + +There is now a Projects page on the Go Dashboard that lists Go programs, +tools, and libraries: + http://godashboard.appspot.com/project + +Other changes: +* 6a, 6l: bug fixes. +* bytes, strings: add Replace. +* cgo: use slash-free relative paths for .so references. +* cmath: correct IsNaN for argument cmplx(Inf, NaN) (thanks Charles L. Dorian). +* codereview: allow multiple email addresses in CONTRIBUTORS. +* doc/codewalk: add Share Memory By Communicating. +* exp/draw/x11: implement the mapping from keycodes to keysyms. +* fmt: Printf: fix bug in handling of %#v, allow other verbs for slices + Scan: fix handling of EOFs. +* gc: bug fixes and optimizations. +* gob: add DecodeValue and EncodeValue, + add support for complex numbers. +* goinstall: support for Bazaar+Launchpad (thanks Gustavo Niemeyer). +* io/ioutil: add TempFile for Windows (thanks Peter Mundy). +* ld: add -u flag to check safe bits; discard old -u, -x flags. +* math: amd64 versions of Exp and Fabs (thanks Charles L. Dorian). +* misc/vim: always override filetype detection for .go files. +* net: add support for DNS SRV requests (thanks Kirklin McDonald), + initial attempt to implement Windows version (thanks Alex Brainman). +* netchan: allow chan of basic types now that gob can handle such, + eliminate the need for a pointer value in Import and Export. +* os/signal: only catch all signals if os/signal package imported. +* regexp: bug fix: need to track whether match begins with fixed prefix. +* rpc: allow non-struct args and reply (they must still be pointers). +* runtime: bug fixes and reorganization. +* strconv: fix bugs in floating-point and base 2 conversions +* syscall: add syscall_bsd.go to zsycall_freebsd_386.go (thanks Peter Mundy), + add socketpair (thanks Ivan Krasin). +* time: implement time zones for Windows (thanks Alex Brainman). +* x509: support non-self-signed certs. +</pre> + +<h2 id="2010-06-21">2010-06-21</h2> + +<pre> +This release includes a language change. The "..." function parameter form is +gone; "...T" remains. Typically, "...interface{}" can be used instead of "...". + +The implementation of Printf has changed in a way that subtly affects its +handling of the fmt.Stringer interface. You may need to make changes to your +code. For details, see: + https://groups.google.com/group/golang-nuts/msg/6fffba90a3e3dc06 + +The reflect package has been changed. If you have code that uses reflect, +it will need to be updated. For details, see: + https://groups.google.com/group/golang-nuts/msg/7a93d07c590e7beb + +Other changes: +* 8l: correct test for sp == top of stack in 8l -K code. +* asn1: allow '*' in PrintableString. +* bytes.Buffer.ReadFrom: fix bug. +* codereview: avoid exception in match (thanks Paolo Giarrusso). +* complex divide: match C99 implementation. +* exp/draw: small draw.drawGlyphOver optimization. +* fmt: Print*: reimplement to switch on type first, + Scanf: improve error message when input does not match format. +* gc: better error messages for interface failures, conversions, undefined symbols. +* go/scanner: report illegal escape sequences. +* gob: substitute slice for map. +* goinstall: process dependencies for package main (thanks Roger Peppe). +* gopack: add S flag to force marking a package as safe, + simplify go metadata code. +* html: sync testdata/webkit to match WebKit tip. +* http: reply to Expect 100-continue requests automatically (thanks Brad Fitzpatrick). +* image: add an Alpha16 type. +* ld: pad Go symbol table out to page boundary (fixes cgo crash). +* misc/vim: reorganize plugin to be easier to use (thanks James Whitehead). +* path: add Base, analogous to Unix basename. +* pkg/Makefile: allow DISABLE_NET_TESTS=1 to disable network tests. +* reflect: add Kind, Type.Bits, remove Int8Type, Int8Value, etc. +* runtime: additional Windows support (thanks Alex Brainman), + correct fault for 16-bit divide on Leopard, + fix 386 signal handler bug. +* strconv: add AtofN, FtoaN. +* string: add IndexFunc and LastIndexFunc (thanks Roger Peppe). +* syslog: use local network for tests. +</pre> + +<h2 id="2010-06-09">2010-06-09</h2> + +<pre> +This release contains many fixes and improvements, including several +clarifications and consolidations to the Language Specification. + +The type checking rules around assignments and conversions are simpler but more +restrictive: assignments no longer convert implicitly from *[10]int to []int +(write x[0:] instead of &x), and conversions can no longer change the names of +types inside composite types. + +The fmt package now includes flexible type-driven (fmt.Scan) and +format-driven (fmt.Scanf) scanners for all basic types. + +* big: bug fix for Quo aliasing problem. +* bufio: change ReadSlice to match description. +* cgo: bug fixes. +* doc: add Google I/O talk and programs, + codereview + Mercurial Queues info (thanks Peter Williams). +* exp/draw: Draw fast paths for the Over operator, + add Rectangle.Eq and Point.In, fix Rectangle.Clip (thanks Roger Peppe). +* fmt: Scan fixes and improvements. +* gc: backslash newline is not a legal escape sequence in strings, + better error message when ~ operator is found, + fix export of complex types, + new typechecking rules. +* go/parser: correct position of empty statement ';'. +* gofmt: fix test script. +* goinstall: use 'git pull' instead of 'git checkout' (thanks Michael Hoisie). +* http: add Head function for making HTTP HEAD requests, + handle status 304 correctly. +* image: add Opaque method to the image types. + make Color.RGBA return 16 bit color instead of 32 bit color. +* io/ioutil: add TempFile. +* math: Pow special cases and additional tests (thanks Charles L. Dorian). +* netchan: improve closing and shutdown. +* os: implement os.FileInfo.*time_ns for windows (thanks Alex Brainman). +* os/signal: correct the regexp for finding Unix signal names (thanks Vinu Rajashekhar). +* regexp: optimizations (thanks Kyle Consalus). +* runtime: fix printing -Inf (thanks Evan Shaw), + finish pchw -> tiny, added gettime for tiny (thanks Daniel Theophanes). +* spec: clean-ups and consolidation. +* syscall: additional Windows compatibility fixes (thanks Alex Brainman). +* test/bench: added regex-dna-parallel.go (thanks Kyle Consalus). +* vector: type-specific Do functions now take f(type) (thanks Michael Hoisie). +</pre> + +<h2 id="2010-05-27">2010-05-27</h2> + +<pre> +A sizeable release, including standard library improvements and a slew of +compiler bug fixes. The three-week interval was largely caused by the team +preparing for Google I/O. + +* big: add Rat type (thanks Evan Shaw), + new features, much performance tuning, cleanups, and more tests. +* bignum: deprecate by moving into exp directory. +* build: allow MAKEFLAGS to be set outside the build scripts (thanks Christopher Wedgwood). +* bytes: add Trim, TrimLeft, TrimRight, and generic functions (thanks Michael Hoisie). +* cgo: fix to permit cgo callbacks from init code. +* cmath: update range of Phase and Polar due to signed zero (thanks Charles L. Dorian). +* codereview: work better with mq (thanks Peter Williams). +* compress: renamings + NewDeflater -> NewWriter + NewInflater -> NewReader + Deflater -> Compressor + Inflater -> Decompressor +* exp/draw/x11: respect $XAUTHORITY, + treat $DISPLAY the same way x-go-bindings does. +* exp/draw: fast path for glyph images, other optimizations, + fix Rectangle.Canon (thanks Roger Peppe). +* fmt: Scan, Scanln: Start of a simple scanning API in the fmt package, + fix Printf crash when given an extra nil argument (thanks Roger Peppe). +* gc: better error when computing remainder of non-int (thanks Evan Shaw), + disallow middot in Go programs, + distinguish array, slice literal in error messages, + fix shift/reduce conflict in go.y export syntax, + fix unsafe.Sizeof on ideal constants, + handle use of builtin function outside function call, + many other bug fixes. +* gob: add support for maps, + add test for indirect maps, slices, arrays. +* godoc: collect package comments from all package files. +* gofmt: don't lose mandatory semicolons, + exclude test w/ illegal syntax from test cases, + fix printing of labels. +* http: prevent crash if remote server is not responding with "HTTP/". +* json: accept escaped slash in string scanner (thanks Michael Hoisie), + fix array -> non-array decoding. +* libmach: skip __nl_symbol_ptr section on OS X. +* math: amd64 versions of Fdim, Fmax, Fmin, + signed zero Sqrt special case (thanks Charles L. Dorian). +* misc/kate: convert isn't a built in function (thanks Evan Shaw). +* net: implement BindToDevice, + implement raw sockets (thanks Christopher Wedgwood). +* netFD: fix race between Close and Read/Write (thanks Michael Hoisie). +* os: add Chtimes function (thanks Brad Fitzpatrick). +* pkg/Makefile: add netchan to standard package list. +* runtime: GOMAXPROCS returns previous value, + allow large map values, + avoid allocation for fixed strings, + correct tracebacks for nascent goroutines, even closures, + free old hashmap pieces during resizing. +* spec: added imaginary literal to semicolon rules (was missing), + fix and clarify syntax of conversions, + simplify section on channel types, + other minor tweaks. +* strconv: Btoui64 optimizations (thanks Kyle Consalus). +* strings: use copy instead of for loop in Map (thanks Kyle Consalus). +* syscall: implement BindToDevice (thanks Christopher Wedgwood), + add Utimes on Darwin/FreeBSD, add Futimes everywhere, + regenerate syscalls for some platforms. +* template: regularize name lookups of interfaces, pointers, and methods. +</pre> + +<h2 id="2010-05-04">2010-05-04</h2> + +<pre> +In this release we renamed the Windows OS target from 'mingw' to 'windows'. +If you are currently building for 'mingw' you should set GOOS=windows instead. + +* 5l, 6l, 8l, runtime: make -s binaries work. +* 5l, 6l, 8l: change ELF header so that strip doesn't destroy binary. +* 8l: fix absolute path detection on Windows. +* big: new functions, optimizations, and cleanups, + add bitwise methods for Int (thanks Evan Shaw). +* bytes: Change IndexAny to look for UTF-8 encoded characters. +* darwin: bsdthread_create can fail; print good error. +* fmt: %T missing print <nil> for nil (thanks Christopher Wedgwood). +* gc: many fixes. +* misc/cgo/gmp: fix bug in SetString. +* net: fix resolv.conf EOF without newline bug (thanks Christopher Wedgwood). +* spec: some small clarifications (no language changes). +* syscall: add EWOULDBLOCK to sycall_nacl.go, + force O_LARGEFILE in Linux open system call, + handle EOF on pipe - special case on Windows (thanks Alex Brainman), + mingw Sleep (thanks Joe Poirier). +* test/bench: import new fasta C reference, update Go, optimizations. +* test: test of static initialization (fails). +* vector: use correct capacity in call to make. +* xml: allow text segments to end at EOF. +</pre> + +<h2 id="2010-04-27">2010-04-27</h2> + +<pre> +This release includes a new Codelab that illustrates the construction of a +simple wiki web application: + http://golang.org/doc/codelab/wiki/ + +It also includes a Codewalk framework for documenting code. See: + http://golang.org/doc/codewalk/ + +Other changes: +* 6g: fix need for parens around array index expression. +* 6l, 8l: include ELF header in PT_LOAD mapping for text segment. +* arm: add android runner script, + support for printing floats. +* big: implemented Karatsuba multiplication, + many fixes and improvements (thanks Evan Shaw). +* bytes: add Next method to Buffer, simplify Read, + shuffle implementation, making WriteByte 50% faster. +* crypto/tls: simpler implementation of record layer. +* exp/eval: fixes (thanks Evan Shaw). +* flag: eliminate unnecessary structs. +* gc: better windows support, + cmplx typecheck bug fix, + more specific error for statements at top level. +* go/parser: don't require unnecessary parens. +* godoc: exclude duplicate entries (thanks Andrei Vieru), + use int64 for timestamps (thanks Christopher Wedgwood). +* gofmt: fine-tune stripping of parentheses, +* json: Marshal, Unmarshal using new scanner, + preserve field name case by default, + scanner, Compact, Indent, and tests, + support for streaming. +* libmach: disassemble MOVLQZX correctly. +* math: more special cases for signed zero (thanks Charles L. Dorian). +* net: add Pipe, + fix bugs in packStructValue (thanks Michael Hoisie), + introduce net.Error interface. +* os: FileInfo: regularize the types of some fields, + create sys_bsd.go (thanks Giles Lean), + mingw bug fixes (thanks Alex Brainman). +* reflect: add FieldByNameFunc (thanks Raif S. Naffah), + implement Set(nil), SetValue(nil) for PtrValue and MapValue. +* regexp: allow escaping of any punctuation. +* rpc/jsonrpc: support for jsonrpc wire encoding. +* rpc: abstract client and server encodings, + add Close() method to rpc.Client. +* runtime: closures, defer bug fix for Native Client, + rename cgo2c, *.cgo to goc2c, *.goc to avoid confusion with real cgo. + several other fixes. +* scanner: implement Peek() to look at the next char w/o advancing. +* strings: add ReadRune to Reader, add FieldsFunc (thanks Kyle Consalus). +* syscall: match linux Setsid function signature to darwin, + mingw bug fixes (thanks Alex Brainman). +* template: fix handling of pointer inside interface. +* test/bench: add fannkuch-parallel.go (thanks Kyle Consalus), + pidigits ~10% performance win by using adds instead of shifts. +* time: remove incorrect time.ISO8601 and add time.RFC3339 (thanks Micah Stetson). +* utf16: add DecodeRune, EncodeRune. +* xml: add support for XML marshalling embedded structs (thanks Raif S. Naffah), + new "innerxml" tag to collect inner XML. +</pre> + +<h2 id="2010-04-13">2010-04-13</h2> + +<pre> +This release contains many changes: + +* 8l: add DOS stub to PE binaries (thanks Evan Shaw). +* cgo: add //export. +* cmath: new complex math library (thanks Charles L. Dorian). +* docs: update to match current coding style (thanks Christopher Wedgwood). +* exp/eval: fix example and add target to Makefile (thanks Evan Shaw). +* fmt: change behaviour of format verb %b to match %x when negative (thanks Andrei Vieru). +* gc: compile s == "" as len(s) == 0, + distinguish fatal compiler bug from error+exit, + fix alignment on non-amd64, + good syntax error for defer func() {} - missing fina (), + implement panic and recover, + zero unnamed return values on entry if func has defer. +* goyacc: change to be reentrant (thanks Roger Peppe). +* io/ioutil: fix bug in ReadFile when Open succeeds but Stat fails. +* kate: update for recent language changes (thanks Evan Shaw). +* libcgo: initial mingw port work - builds but untested (thanks Joe Poirier). +* math: new functions and special cases (thanks Charles L. Dorian) +* net: use chan bool instead of chan *netFD to avoid cycle. +* netchan: allow client to send as well as receive. +* nntp: new package, NNTP client (thanks Conrad Meyer). +* os: rename os.Dir to os.FileInfo. +* rpc: don't log normal EOF, + fix ServeConn to block as documented. +* runtime: many bug fixes, better ARM support. +* strings: add IndexRune, Trim, TrimLeft, TrimRight, etc (thanks Michael Hoisie). +* syscall: implement some mingw syscalls required by os (thanks Alex Brainman). +* test/bench: add k-nucleotide-parallel (thanks Kyle Consalus). +* Unicode: add support for Turkish case mapping. +* xgb: move from the main repository to http://code.google.com/p/x-go-binding/ +</pre> + +<h2 id="2010-03-30">2010-03-30</h2> + +<pre> +This release contains three language changes: + +1. Accessing a non-existent key in a map is no longer a run-time error. +It now evaluates to the zero value for that type. For example: + x := myMap[i] is now equivalent to: x, _ := myMap[i] + +2. It is now legal to take the address of a function's return value. +The return values are copied back to the caller only after deferred +functions have run. + +3. The functions panic and recover, intended for reporting and recovering from +failure, have been added to the spec: + http://golang.org/doc/go_spec.html#Handling_panics +In a related change, panicln is gone, and panic is now a single-argument +function. Panic and recover are recognized by the gc compilers but the new +behavior is not yet implemented. + +The ARM build is broken in this release; ARM users should stay at release.2010-03-22. + +Other changes: +* bytes, strings: add IndexAny. +* cc/ld: Add support for #pragma dynexport, + Rename dynld to dynimport throughout. Cgo users will need to rerun cgo. +* expvar: default publishings for cmdline, memstats +* flag: add user-defined flag types. +* gc: usual bug fixes +* go/ast: generalized ast filtering. +* go/printer: avoid reflect in print. +* godefs: fix handling of negative constants. +* godoc: export pprof debug information, exported variables, + support for filtering of command-line output in -src mode, + use http GET for remote search instead of rpc. +* gofmt: don't convert multi-line functions into one-liners, + preserve newlines in multiline selector expressions (thanks Risto Jaakko Saarelma). +* goinstall: include command name in error reporting (thanks Andrey Mirtchovski) +* http: add HandleFunc as shortcut to Handle(path, HandlerFunc(func)) +* make: use actual dependency for install +* math: add J1, Y1, Jn, Yn, J0, Y0 (Bessel functions) (thanks Charles L. Dorian) +* prof: add pprof from google-perftools +* regexp: don't return non-nil *Regexp if there is an error. +* runtime: add Callers, + add malloc sampling, pprof interface, + add memory profiling, more statistics to runtime.MemStats, + implement missing destroylock() (thanks Alex Brainman), + more malloc statistics, + run all finalizers in a single goroutine, + Goexit runs deferred calls. +* strconv: add Atob and Btoa, + Unquote could wrongly return a nil error on error (thanks Roger Peppe). +* syscall: add IPV6 constants, + add syscall_bsd.go for Darwin and other *BSDs (thanks Giles Lean), + implement SetsockoptString (thanks Christopher Wedgwood). +* websocket: implement new protocol (thanks Fumitoshi Ukai). +* xgb: fix request length and request size (thanks Firmansyah Adiputra). +* xml: add CopyToken (thanks Kyle Consalus), + add line numbers to syntax errors (thanks Kyle Consalus), + use io.ReadByter in place of local readByter (thanks Raif S. Naffah). +</pre> + +<h2 id="2010-03-22">2010-03-22</h2> + +<pre> +With this release we announce the launch of the Go Blog: + http://blog.golang.org/ +The first post is a brief update covering what has happened since the launch. + +This release contains some new packages and functionality, and many fixes: +* 6g/8g: fix issues with complex data types, other bug fixes. +* Makefiles: refactored to make writing external Makefiles easier. +* crypto/rand: new package. +* godoc: implemented command-line search via RPC, + improved comment formatting: recognize URLs. +* gofmt: more consistent formatting of const/var decls. +* http: add Error helper function, + add ParseQuery (thanks Petar Maymounkov), + change RawPath to mean raw path, not raw everything-after-scheme. +* image/jpeg: fix typos. +* json: add MarshalIndent (accepts user-specified indent string). +* math: add Gamma function (thanks Charles L. Dorian). +* misc/bbedit: support for cmplx, real, imag (thanks Anthony Starks). +* misc/vim: add new complex types, functions and literals. +* net: fix IPMask.String not to crash on all-0xff mask. +* os: drop File finalizer after normal Close. +* runtime: add GOROOT and Version, + lock finalizer table accesses. +* sha512: add sha384 (truncated version) (thanks Conrad Meyer). +* syscall: add const ARCH, analogous to OS. +* syscall: further additions to mingw port (thanks Alex Brainman). +* template: fixed html formatter []byte input bug. +* utf16: new package. +* version.bash: cope with ancient Mercurial. +* websocket: use URL.RawPath to construct WebSocket-Location: header. +</pre> + +<h2 id="2010-03-15">2010-03-15</h2> + +<pre> +This release includes a language change: support for complex numbers. + http://golang.org/doc/go_spec.html#Imaginary_literals + http://golang.org/doc/go_spec.html#Complex_numbers +There is no library support as yet. + +This release also includes the goinstall command-line tool. + http://golang.org/cmd/goinstall/ + http://groups.google.com/group/golang-nuts/t/f091704771128e32 + +* 5g/6g/8g: fix double function call in slice. +* arm: cleanup build warnings. (thanks Dean Prichard) +* big: fix mistakes with probablyPrime. +* bufio: add WriteRune. +* bytes: add ReadRune and WriteRune to bytes.Buffer. +* cc: stack split bug fix. +* crypto: add SHA-224 to sha256, add sha512 package. (thanks Conrad Meyer) +* crypto/ripemd160: new package. (thanks Raif S. Naffah) +* crypto/rsa: don't use safe primes. +* gc: avoid fixed length buffer cleanbuf. (thanks Dean Prichard) + better compilation of floating point += + fix crash on complicated arg to make slice. + remove duplicate errors, give better error for I.(T) +* godoc: support for multiple packages in a directory, other fixes. +* gofmt: bug fixes. +* hash: add Sum64 interface. +* hash/crc32: add Update function. +* hash/crc64: new package implementing 64-bit CRC. +* math: add ilogb, logb, remainder. (thanks Charles L. Dorian) +* regexp: add ReplaceAllFunc, ReplaceAllStringFunc. +* runtime: clock garbage collection on bytes allocated, not pages in use. +* strings: make Split(s, "", n) faster. (thanks Spring Mc) +* syscall: minimal mingw version of syscall. (thanks Alex Brainman) +* template: add ParseFile, MustParseFile. +</pre> + +<h2 id="2010-03-04">2010-03-04</h2> + +<pre> +There is one language change: the ability to convert a string to []byte or +[]int. This deprecates the strings.Bytes and strings.Runes functions. +You can convert your existing sources using these gofmt commands: + gofmt -r 'strings.Bytes(x) -> []byte(x)' -w file-or-directory-list + gofmt -r 'strings.Runes(x) -> []int(x)' -w file-or-directory-list +After running these you might need to delete unused imports of the "strings" +package. + +Other changes and fixes: +* 6l/8l/5l: add -r option +* 8g: make a[byte(x)] truncate x +* codereview.py: fix for compatibility with hg >=1.4.3 +* crypto/blowfish: new package (thanks Raif S. Naffah) +* dashboard: more performance tuning +* fmt: use String method in %q to get the value to quote. +* gofmt: several cosmetic changes +* http: fix handling of Connection: close, bug in http.Post +* net: correct DNS configuration, + fix network timeout boundary condition, + put [ ] around IPv6 addresses for Dial. +* path: add Match, + fix bug in Match with non-greedy stars (thanks Kevin Ballard) +* strings: delete Bytes, Runes (see above) +* tests: an Eratosthenesque concurrent prime sieve (thanks Anh Hai Trinh) +</pre> + +<h2 id="2010-02-23">2010-02-23</h2> + +<pre> +This release is mainly bug fixes and a little new code. +There are no language changes. + +6g/5g/8g: bug fixes +8a/8l: Added FCMOVcc instructions (thanks Evan Shaw and Charles Dorian) +crypto/x509: support certificate creation +dashboard: caching to avoid datastore queries +exec: add dir argument to Run +godoc: bug fixes and code cleanups +http: continued implementation and bug fixes (thanks Petar Maymounkov) +json: fix quoted strings in Marshal (thanks Sergei Skorobogatov) +math: more functions, test cases, and benchmarks (thanks Charles L. Dorian) +misc/bbedit: treat predeclared identifiers as "keywords" (thanks Anthony Starks) +net: disable UDP server test (flaky on various architectures) +runtime: work around Linux kernel bug in futex, + pchw is now tiny +sync: fix to work on armv5 (thanks Dean Prichard) +websocket: fix binary frame size decoding (thanks Timo Savola) +xml: allow unquoted attribute values in non-Strict mode (thanks Amrut Joshi) + treat bool as value in Unmarshal (thanks Michael Hoisie) +</pre> + +<h2 id="2010-02-17">2010-02-17</h2> + +<pre> +There are two small language changes: +* NUL bytes may be rejected in souce files, and the tools do reject them. +* Conversions from string to []int and []byte are defined but not yet implemented. + +Other changes and fixes: +* 5a/6a/8a/5c/6c/8c: remove fixed-size arrays for -I and -D options (thanks Dean Prichard) +* 5c/6c/8c/5l/6l/8l: add -V flag to display version number +* 5c/6c/8c: use "cpp" not "/bin/cpp" for external preprocessor (thanks Giles Lean) +* 8a/8l: Added CMOVcc instructions (thanks Evan Shaw) +* 8l: pe executable building code changed to include import table for kernel32.dll functions (thanks Alex Brainman) +* 5g/6g/8g: bug fixes +* asn1: bug fixes and additions (incl marshalling) +* build: fix build for Native Client, Linux/ARM +* dashboard: show benchmarks, add garbage collector benchmarks +* encoding/pem: add marshalling support +* exp/draw: fast paths for a nil mask +* godoc: support for directories outside $GOROOT +* http: sort header keys when writing Response or Request to wire (thanks Petar Maymounkov) +* math: special cases and new functions (thanks Charles Dorian) +* mime: new package, used in http (thanks Michael Hoisie) +* net: dns bug fix - use random request id +* os: finalize File, to close fd. +* path: make Join variadic (thanks Stephen Weinberg) +* regexp: optimization bug fix +* runtime: misc fixes and optimizations +* syscall: make signature of Umask on OS X, FreeBSD match Linux. (thanks Giles Lean) +</pre> + +<h2 id="2010-02-04">2010-02-04</h2> + +<pre> +There is one language change: support for ...T parameters: + http://golang.org/doc/go_spec.html#Function_types + +You can now check build status on various platforms at the Go Dashboard: + http://godashboard.appspot.com + +* 5l/6l/8l: several minor fixes +* 5a/6a/8a/5l/6l/8l: avoid overflow of symb buffer (thanks Dean Prichard) +* compress/gzip: gzip deflater (i.e., writer) +* debug/proc: add mingw specific build stubs (thanks Joe Poirier) +* exp/draw: separate the source-point and mask-point in Draw +* fmt: handle nils safely in Printf +* gccgo: error messages now match those of gc +* godoc: several fixes +* http: bug fixes, revision of Request/Response (thanks Petar Maymounkov) +* image: new image.A type to represent anti-aliased font glyphs + add named colors (e.g. image.Blue), suitable for exp/draw +* io: fixed bugs in Pipe +* malloc: merge into package runtime +* math: fix tests on FreeBSD (thanks Devon H. O'Dell) + add functions; update tests and special cases (thanks Charles L. Dorian) +* os/signal: send SIGCHLDs to Incoming (thanks Chris Wedgwood) +* reflect: add StringHeader to reflect +* runtime: add SetFinalizer +* time: Sleep through interruptions (thanks Chris Wedgwood) + add RFC822 formats + experimental implemenation of Ticker using two goroutines for all tickers +* xml: allow underscores in XML element names (thanks Michael Hoisie) + allow any scalar type in xml.Unmarshal +</pre> + +<h2 id="2010-01-27">2010-01-27</h2> + +<pre> +There are two small language changes: the meaning of chan <- chan int +is now defined, and functions returning functions do not need to +parenthesize the result type. + +There is one significant implementation change: the compilers can +handle multiple packages using the same name in a single binary. +In the gc compilers, this comes at the cost of ensuring that you +always import a particular package using a consistent import path. +In the gccgo compiler, the cost is that you must use the -fgo-prefix +flag to pass a unique prefix (like the eventual import path). + +5a/6a/8a: avoid use of fixed-size buffers (thanks Dean Prichard) +5g, 6g, 8g: many minor bug fixes +bufio: give Writer.WriteString same signature as bytes.Buffer.WriteString. +container/list: PushFrontList, PushBackList (thanks Jan Hosang) +godoc: trim spaces from search query (thanks Christopher Wedgwood) +hash: document that Sum does not change state, fix crypto hashes +http: bug fixes, revision of Request/Response (thanks Petar Maymounkov) +math: more handling of IEEE 754 special cases (thanks Charles Dorian) +misc/dashboard: new build dashboard +net: allow UDP broadcast, + use /etc/hosts to resolve names (thanks Yves Junqueira, Michael Hoisie) +netchan: beginnings of new package for connecting channels across a network +os: allow FQDN in Hostname test (thanks Icarus Sparry) +reflect: garbage collection bug in Call +runtime: demo of Go on raw (emulated) hw in runtime/pchw, + performance fix on OS X +spec: clarify meaning of chan <- chan int, + func() func() int is allowed now, + define ... T (not yet implemented) +template: can use interface values +time: fix for +0000 time zone, + more robust tick.Stop. +xgb: support for authenticated connections (thanks Firmansyah Adiputra) +xml: add Escape (thanks Stephen Weinberg) +</pre> + +<h2 id="2010-01-13">2010-01-13</h2> + +<pre> +This release is mainly bug fixes with a little new code. +There are no language changes. + +build: $GOBIN should no longer be required in $PATH (thanks Devon H. O'Dell), + new package target "make bench" to run benchmarks +8g: faster float -> uint64 conversion (thanks Evan Shaw) +5g, 6g, 8g: + clean opnames.h to avoid stale errors (thanks Yongjian Xu), + a handful of small compiler fixes +5g, 6g, 8g, 5l, 6l, 8l: ignore $GOARCH, which is implied by name of tool +6prof: support for writing input files for google-perftools's pprof +asn1: fix a few structure-handling bugs +cgo: many bug fixes (thanks Devon H. O'Dell) +codereview: repeated "hg mail" sends "please take another look" +gob: reserve ids for future expansion +godoc: distinguish HTML generation from plain text HTML escaping (thanks Roger Peppe) +gofmt: minor bug fixes, removed -oldprinter flag +http: add CanonicalPath (thanks Ivan Krasin), + avoid header duplication in Response.Write, + correctly escape/unescape URL sections +io: new interface ReadByter +json: better error, pointer handling in Marshal (thanks Ivan Krasin) +libmach: disassembly of FUCOMI, etc (thanks Evan Shaw) +math: special cases for most functions and 386 hardware Sqrt (thanks Charles Dorian) +misc/dashboard: beginning of a build dashboard at godashboard.appspot.com. +misc/emacs: handling of new semicolon rules (thanks Austin Clements), + empty buffer bug fix (thanks Kevin Ballard) +misc/kate: highlighting improvements (tahnks Evan Shaw) +os/signal: add signal names: signal.SIGHUP, etc (thanks David Symonds) +runtime: preliminary Windows support (thanks Hector Chu), + preemption polling to reduce garbage collector pauses +scanner: new lightweight scanner package +template: bug fix involving spaces before a delimited block +test/bench: updated timings +time: new Format, Parse functions +</pre> + +<h2 id="2010-01-05">2010-01-05</h2> + +<pre> +This release is mainly bug fixes. There are no language changes. + +6prof: now works on 386 +8a, 8l: add FCOMI, FCOMIP, FUCOMI, and FUCOMIP (thanks Evan Shaw) +big: fix ProbablyPrime on small numbers +container/vector: faster []-based implementation (thanks Jan Mercl) +crypto/tls: extensions and Next Protocol Negotiation +gob: one encoding bug fix, one decoding bug fix +image/jpeg: support for RST markers +image/png: support for transparent paletted images +misc/xcode: improved support (thanks Ken Friedenbach) +net: return nil Conn on error from Dial (thanks Roger Peppe) +regexp: add Regexp.NumSubexp (thanks Peter Froehlich) +syscall: add Nanosleep on FreeBSD (thanks Devon H. O'Dell) +template: can use map in .repeated section + +There is now a public road map, in the repository and online +at <a href="http://golang.org/doc/devel/roadmap.html">http://golang.org/doc/devel/roadmap.html</a>. +</pre> + +<h2 id="2009-12-22">2009-12-22</h2> + +<pre> +Since the last release there has been one large syntactic change to +the language, already discussed extensively on this list: semicolons +are now implied between statement-ending tokens and newline characters. +See http://groups.google.com/group/golang-nuts/t/5ee32b588d10f2e9 for +details. + +By default, gofmt now parses and prints the new lighter weight syntax. +To convert programs written in the old syntax, you can use: + + gofmt -oldparser -w *.go + +Since everything was being reformatted anyway, we took the opportunity to +change the way gofmt does alignment. Now gofmt uses tabs at the start +of a line for basic code alignment, but it uses spaces for alignment of +interior columns. Thus, in an editor with a fixed-width font, you can +choose your own tab size to change the indentation, and no matter what +tab size you choose, columns will be aligned properly. + + +In addition to the syntax and formatting changes, there have been many +smaller fixes and updates: + +6g,8g,5g: many bug fixes, better registerization, + build process fix involving mkbuiltin (thanks Yongjian Xu), + method expressions for concrete types +8l: support for Windows PE files (thanks Hector Chu) +bytes: more efficient Buffer handling +bytes, strings: new function Fields (thanks Andrey Mirtchovski) +cgo: handling of enums (thanks Moriyoshi Koizumi), + handling of structs with bit fields, multiple files (thanks Devon H. O'Dell), + installation of .so to non-standard locations +crypto/sha256: new package for SHA 256 (thanks Andy Davis) +encoding/binary: support for slices of fixed-size values (thanks Maxim Ushakov) +exp/vector: experimental alternate vector representation (thanks Jan Mercl) +fmt: %p for chan, map, slice types +gob: a couple more bug fixes +http: support for basic authentication (thanks Ivan Krasin) +image/jpeg: basic JPEG decoder +math: correct handling of Inf and NaN in Pow (thanks Charles Dorian) +misc/bash: completion file for bash (thanks Alex Ray) +os/signal: support for handling Unix signals (thanks David Symonds) +rand: Zipf-distributed random values (thanks William Josephson) +syscall: correct error return bug on 32-bit machines (thanks Christopher Wedgwood) +syslog: new package for writing to Unix syslog daemon (thanks Yves Junqueira) +template: will automatically invoke niladic methods +time: new ISO8601 format generator (thanks Ben Olive) +xgb: converted generator to new syntax (thanks Tor Andersson) +xml: better mapping of tag names to Go identifiers (thanks Kei Son), + better handling of unexpected EOF (thanks Arvindh Rajesh Tamilmani) +</pre> + +<h2 id="2009-12-09">2009-12-09</h2> + +<pre> +Since the last release there are two changes to the language: + +* new builtin copy(dst, src) copies n = min(len(dst), len(src)) + elements to dst from src and returns n. It works correctly + even if dst and src overlap. bytes.Copy is gone. + Convert your programs using: + gofmt -w -r 'bytes.Copy(d, s) -> copy(d, s)' *.go + +* new syntax x[lo:] is shorthand for x[lo:len(x)]. + Convert your programs using: + gofmt -w -r 'a[b:len(a)] -> a[b:]' *.go + +In addition, there have been many smaller fixes and updates: + +* 6g/8g/5g: many bug fixes +* 8g: fix 386 floating point stack bug (thanks Charles Dorian) +* all.bash: now works even when $GOROOT has spaces (thanks Sergio Luis O. B. Correia), + starting to make build work with mingw (thanks Hector Chu), + FreeBSD support (thanks Devon O'Dell) +* big: much faster on 386. +* bytes: new function IndexByte, implemented in assembly + new function Runes (thanks Peter Froehlich), + performance tuning in bytes.Buffer. +* codereview: various bugs fixed +* container/vector: New is gone; just declare a Vector instead. + call Resize to set len and cap. +* cgo: many bug fixes (thanks Eden Li) +* crypto: added MD4 (thanks Chris Lennert), + added XTEA (thanks Adrian O'Grady). +* crypto/tls: basic client +* exp/iterable: new functions (thanks Michael Elkins) +* exp/nacl: native client tree builds again +* fmt: preliminary performance tuning +* go/ast: more powerful Visitor (thanks Roger Peppe) +* gob: a few bug fixes +* gofmt: better handling of standard input, error reporting (thanks Fazlul Shahriar) + new -r flag for rewriting programs +* gotest: support for Benchmark functions (thanks Trevor Strohman) +* io: ReadFile, WriteFile, ReadDir now in separate package io/ioutil. +* json: new Marshal function (thanks Michael Hoisie), + better white space handling (thanks Andrew Skiba), + decoding into native data structures (thanks Sergey Gromov), + handling of nil interface values (thanks Ross Light). +* math: correct handling of sin/cos of large angles +* net: better handling of Close (thanks Devon O'Dell and Christopher Wedgwood) + support for UDP broadcast (thanks Jonathan Wills), + support for empty packets +* rand: top-level functions now safe to call from multiple goroutines +(thanks Roger Peppe). +* regexp: a few easy optimizations +* rpc: better error handling, a few bug fixes +* runtime: better signal handling on OS X, malloc fixes, + global channel lock is gone. +* sync: RWMutex now allows concurrent readers (thanks Péter Szabó) +* template: can use maps as data (thanks James Meneghello) +* unicode: updated to Unicode 5.2. +* websocket: new package (thanks Fumitoshi Ukai) +* xgb: preliminary X Go Bindings (thanks Tor Andersson) +* xml: fixed crash (thanks Vish Subramanian) +* misc: bbedit config (thanks Anthony Starks), + kate config (thanks Evan Shaw) +</pre> diff --git a/doc/docs.html b/doc/docs.html new file mode 100644 index 000000000..9fd3dcebe --- /dev/null +++ b/doc/docs.html @@ -0,0 +1,236 @@ +<!-- title Documentation --> + +<div class="left-column"> + +<h2 id="learning">Learning Go</h2> + +<p> +If you're new to Go, we recommend you work through the +<a href="go_tutorial.html">tutorial</a>. The +<a href="go_spec.html">language specification</a> has all the details should +you want to explore. +</p> +<p> +Once you've learned a little about the language, +<a href="effective_go.html">Effective Go</a> will help you learn the style and +idioms of programming in Go. +</p> + +<h3 id="orig_tutorial"><a href="go_tutorial.html">A Tutorial for the Go Programming Language</a></h3> +<p> +The first tutorial. An introductory text that touches upon several core +concepts: syntax, types, allocation, constants, I/O, sorting, printing, +goroutines, and channels. +</p> + +<h3 id="course_notes">Course Notes</h3> +<p> +Slides from a 3-day course about the Go programming language. +A more thorough introduction than the tutorial. +</p> +<ul> +<li><a href="GoCourseDay1.pdf">Day 1: Basics</a> <small>[270KB PDF]</small> +<li><a href="GoCourseDay2.pdf">Day 2: Types, Methods, Interfaces</a> <small>[270KB PDF]</small> +<li><a href="GoCourseDay3.pdf">Day 3: Concurrency and Communication</a> <small>[180KB PDF]</small> +</ul> + +<h3 id="effective_go"><a href="effective_go.html">Effective Go</a></h3> +<p> +A document that gives tips for writing clear, idiomatic Go code. +A must read for any new Go programmer. It augments the tutorial and +the language specification, both of which should be read first. +</p> + +<h3 id="go_faq"><a href="go_faq.html">Frequently Asked Questions (FAQ)</a></h3> +<p> +Answers to common questions about Go. +</p> + +<h3 id="code"><a href="code.html">How to write Go code</a></h3> +<p> +How to write a new package and how to test code. +</p> + +<h3 id="codelab_wiki"><a href="codelab/wiki/">Codelab: Writing Web Applications</a></h3> +<p> +This codelab takes the reader through the creation of a simple wiki web +application. It touches on structs, methods, file I/O, http, regular expressions, +and closures. +</p> + +<h3 id="codewalks"><a href="codewalk/">Codewalks</a></h3> +<p> +Guided tours of Go programs. +</p> + +<h3 id="go_for_cpp_programmers"><a href="go_for_cpp_programmers.html">Go for C++ Programmers</a></h3> +<p> +An introduction to Go for C++ programmers. +</p> + +<h2 id="tutorials_nonenglish">Non-English Documentation</h2> + +<h3 id="docs_be">Belarusian — Беларуская</h3> + +<ul> +<li><a href="http://www.designcontest.com/show/faq-be">faq-be</a> - Frequently Asked Questions.</li> +</ul> + +<h3 id="docs_cn">Chinese — 中文</h3> + +<ul> +<li><a href="http://code.google.com/p/golang-china/">golang-china</a> - a broad range of Go documentation.</li> +<li><a href="http://code.google.com/p/ac-me/downloads/detail?name=fango.pdf">Effective Go and Tutorial</a></li> +</ul> + +<h3 id="docs_de">German — Deutsch</h3> + +<ul> +<li><a href="http://bitloeffel.de/DOC/golang/go_tutorial_de.html">Eine Anleitung zum Programmieren in Go</a> - the Go Tutorial.</li> +<li><a href="http://bitloeffel.de/DOC/golang/effective_go_de.html">Wirkungsvoll Go programmieren</a> - Effective Go.</li> +<li><a href="http://bitloeffel.de/DOC/golang/code_de.html">Wie man Go-Kode schreibt</a> - How to Write Go Code.</li> +</ul> + +<h3 id="docs_jp">Japanese — 日本語</h3> +<ul> +<li><a href="http://golang.jp/">golang.jp</a> - Go documentation and news. +</ul> + +<h3 id="docs_kr">Korean — 한국어</h3> +<ul> +<li><a href="http://code.google.com/p/golang-korea">golang-korea</a> - Go documentation and news. +</ul> + +<h3 id="docs_ru">Russian — Русский</h3> +<ul> +<li><a href="http://golanguage.ru/">golanguage.ru</a> - Go documentation. +</ul> + +</div> + + +<div class="right-column"> + +<h2 id="References">References</h2> + +<p>Keep these under your pillow.</p> + +<h3 id="pkg"><a href="/pkg/">Package Documentation</a></h3> +<p> +The built-in documentation for the Go standard library. +</p> + +<h3 id="cmd"><a href="/cmd/">Command Documentation</a></h3> +<p> +The built-in documentation for the Go tools. +</p> + +<h3 id="spec"><a href="go_spec.html">Language Specification</a></h3> +<p> +The official Go Language specification. +</p> + +<h3 id="release"><a href="devel/release.html">Release History</a></h3> +<p>A summary of the changes between Go releases.</p> + +<h3 id="go_mem"><a href="go_mem.html">The Go Memory Model</a></h3> +<p> +A document that specifies the conditions under which reads of a variable in +one goroutine can be guaranteed to observe values produced by writes to the +same variable in a different goroutine. +</p> + +<h2 id="videos_talks">Videos and Talks</h2> + +<h3 id="writing_web_apps"><a href="http://www.youtube.com/watch?v=-i0hat7pdpk">Writing Web Apps in Go</a></h3> +<p> +A talk by Rob Pike and Andrew Gerrand presented at Google I/O 2011. +It walks through the construction and deployment of a simple web application +and unveils the <a href="http://blog.golang.org/2011/05/go-and-google-app-engine.html">Go runtime for App Engine</a>. +See the <a href="/doc/talks/io2011/Writing_Web_Apps_in_Go.pdf">presentation slides</a>. +</p> + +<h3 id="real_world_go"><a href="http://www.youtube.com/watch?v=7QDVRowyUQA">Real World Go</a></h3> +<p> +A talk by Andrew Gerrand presented at Google I/O Bootcamp 2011. +It gives a broad overview of Go's type system and concurrency model +and provides four examples of Go programs that solve real problems. +See the <a href="/doc/talks/io2011/Real_World_Go.pdf">presentation slides</a>. +</p> + +<h3 id="go_programming"><a href="http://www.youtube.com/watch?v=jgVhBThJdXc">Go Programming</a></h3> +<p> +A presentation delivered by Rob Pike and Russ Cox at Google I/O 2010. It +illustrates how programming in Go differs from other languages through a set of +examples demonstrating features particular to Go. These include concurrency, +embedded types, methods on any type, and program construction using interfaces. +</p> + +<h3 id="practical_go_programming"><a href="http://osdc.blip.tv/file/4432146/">Practical Go Programming</a></h3> +<p> +This talk presents the development of a complete web application in Go. +It looks at design, storage, concurrency, and scaling issues in detail, using +the simple example of an URL shortening service. +See the <a href="http://wh3rd.net/practical-go/">presentation slides</a>. +</p> + +<h3 id="techtalk"><a href="http://www.youtube.com/watch?v=rKnDgT73v8s">The Go Tech Talk</a></h3> +<p> +An hour-long talk delivered by Rob Pike at Google in October 2009. +The language's first public introduction. (See the <a href="talks/go_talk-20091030.pdf">slides in PDF format</a>.) The language has changed since it was made, +but it's still a good introduction. +</p> + +<h3 id="gocoding_channel"><a href="http://www.youtube.com/gocoding">gocoding YouTube Channel</a></h3> +<p> +A YouTube channel that includes screencasts and other Go-related videos: +</p> +<ul> +<li><a href="http://www.youtube.com/gocoding#p/u/0/jDWBJOXs_iI">Screencast: Writing Go Packages</a> - writing, building, and distributing Go packages.</li> +<li><a href="http://www.youtube.com/watch?v=3brH0zOqm0w">Screencast: Testing Go Packages</a> - writing unit tests and benchmarking Go packages.</li> +</ul> + +<h3 id="jaoo_go"><a href="/doc/ExpressivenessOfGo.pdf">The Expressiveness Of Go</a></h3> +<p> +A discussion of the qualities that make Go an expressive and comprehensible +language. The talk was presented by Rob Pike at JAOO 2010. +The recording of the event was lost due to a hardware error. +</p> + +<h3 id="oscon_go"><a href="http://www.oscon.com/oscon2010/public/schedule/detail/14760">Another Go at Language Design</a></h3> +<p> +A tour, with some background, of the major features of Go, intended for +an audience new to the language. The talk was presented at OSCON 2010. +See the <a href="http://assets.en.oreilly.com/1/event/45/Another%20Go%20at%20Language%20Design%20Presentation.pdf">presentation slides</a>. +</p> +<p> +This talk was also delivered at Sydney University in September 2010. A video +of the lecture is available +<a href="http://sydney.edu.au/engineering/it/videos/seminar_pike">here</a>. +</p> + +<h3 id="emerging_go"><a href="http://www.oscon.com/oscon2010/public/schedule/detail/15464">Go Emerging Languages Conference Talk</a></h3> +<p> +Rob Pike's Emerging Languages Conference presentation delivered in July 2010. See the <a href="http://assets.en.oreilly.com/1/event/45/Go%20Presentation.pdf">presentation slides</a>. Abstract: +</p> +<p><i> +Go’s approach to concurrency differs from that of many languages, even those +(such as Erlang) that make concurrency central, yet it has deep roots. The path +from Hoare’s 1978 paper to Go provides insight into how and why Go works as it +does. +</i></p> + +<h3 id="go_frontend_gcc"><a href="talks/gofrontend-gcc-summit-2010.pdf">The Go frontend for GCC</a></h3> +<p> +A description of the Go language frontend for gcc. +Ian Lance Taylor's paper delivered at the GCC Summit 2010. +</p> + +<h3 id="promo_video"><a href="http://www.youtube.com/watch?v=wwoWei-GAPo">The Go Promo Video</a></h3> +<p> +A short promotional video featuring Russ Cox demonstrating Go's fast compiler. +</p> + +</div> + +<div class="end-columns"></div> diff --git a/doc/effective_go.html b/doc/effective_go.html new file mode 100644 index 000000000..37cb516b0 --- /dev/null +++ b/doc/effective_go.html @@ -0,0 +1,3041 @@ +<!-- Effective Go --> + +<h2 id="introduction">Introduction</h2> + +<p> +Go is a new language. Although it borrows ideas from +existing languages, +it has unusual properties that make effective Go programs +different in character from programs written in its relatives. +A straightforward translation of a C++ or Java program into Go +is unlikely to produce a satisfactory result—Java programs +are written in Java, not Go. +On the other hand, thinking about the problem from a Go +perspective could produce a successful but quite different +program. +In other words, +to write Go well, it's important to understand its properties +and idioms. +It's also important to know the established conventions for +programming in Go, such as naming, formatting, program +construction, and so on, so that programs you write +will be easy for other Go programmers to understand. +</p> + +<p> +This document gives tips for writing clear, idiomatic Go code. +It augments the <a href="go_spec.html">language specification</a> +and the <a href="go_tutorial.html">tutorial</a>, both of which you +should read first. +</p> + +<h3 id="examples">Examples</h3> + +<p> +The <a href="/src/pkg/">Go package sources</a> +are intended to serve not +only as the core library but also as examples of how to +use the language. +If you have a question about how to approach a problem or how something +might be implemented, they can provide answers, ideas and +background. +</p> + + +<h2 id="formatting">Formatting</h2> + +<p> +Formatting issues are the most contentious +but the least consequential. +People can adapt to different formatting styles +but it's better if they don't have to, and +less time is devoted to the topic +if everyone adheres to the same style. +The problem is how to approach this Utopia without a long +prescriptive style guide. +</p> + +<p> +With Go we take an unusual +approach and let the machine +take care of most formatting issues. +The <code>gofmt</code> tool reads a Go program +and emits the source in a standard style of indentation +and vertical alignment, retaining and if necessary +reformatting comments. +If you want to know how to handle some new layout +situation, run <code>gofmt</code>; if the answer doesn't +seem right, rearrange your program (or file a bug about <code>gofmt</code>), +don't work around it. +</p> + +<p> +As an example, there's no need to spend time lining up +the comments on the fields of a structure. +<code>Gofmt</code> will do that for you. Given the +declaration +</p> + +<pre> +type T struct { + name string // name of the object + value int // its value +} +</pre> + +<p> +<code>gofmt</code> will line up the columns: +</p> + +<pre> +type T struct { + name string // name of the object + value int // its value +} +</pre> + +<p> +All Go code in the standard packages has been formatted with <code>gofmt</code>. +</p> + + +<p> +Some formatting details remain. Very briefly, +</p> + +<dl> + <dt>Indentation</dt> + <dd>We use tabs for indentation and <code>gofmt</code> emits them by default. + Use spaces only if you must. + </dd> + <dt>Line length</dt> + <dd> + Go has no line length limit. Don't worry about overflowing a punched card. + If a line feels too long, wrap it and indent with an extra tab. + </dd> + <dt>Parentheses</dt> + <dd> + Go needs fewer parentheses: control structures (<code>if</code>, + <code>for</code>, <code>switch</code>) do not have parentheses in + their syntax. + Also, the operator precedence hierarchy is shorter and clearer, so +<pre> +x<<8 + y<<16 +</pre> + means what the spacing implies. + </dd> +</dl> + +<h2 id="commentary">Commentary</h2> + +<p> +Go provides C-style <code>/* */</code> block comments +and C++-style <code>//</code> line comments. +Line comments are the norm; +block comments appear mostly as package comments and +are also useful to disable large swaths of code. +</p> + +<p> +The program—and web server—<code>godoc</code> processes +Go source files to extract documentation about the contents of the +package. +Comments that appear before top-level declarations, with no intervening newlines, +are extracted along with the declaration to serve as explanatory text for the item. +The nature and style of these comments determines the +quality of the documentation <code>godoc</code> produces. +</p> + +<p> +Every package should have a <i>package comment</i>, a block +comment preceding the package clause. +For multi-file packages, the package comment only needs to be +present in one file, and any one will do. +The package comment should introduce the package and +provide information relevant to the package as a whole. +It will appear first on the <code>godoc</code> page and +should set up the detailed documentation that follows. +</p> + +<pre> +/* + Package regexp implements a simple library for + regular expressions. + + The syntax of the regular expressions accepted is: + + regexp: + concatenation { '|' concatenation } + concatenation: + { closure } + closure: + term [ '*' | '+' | '?' ] + term: + '^' + '$' + '.' + character + '[' [ '^' ] character-ranges ']' + '(' regexp ')' +*/ +package regexp +</pre> + +<p> +If the package is simple, the package comment can be brief. +</p> + +<pre> +// Package path implements utility routines for +// manipulating slash-separated filename paths. +</pre> + +<p> +Comments do not need extra formatting such as banners of stars. +The generated output may not even be presented in a fixed-width font, so don't depend +on spacing for alignment—<code>godoc</code>, like <code>gofmt</code>, +takes care of that. +The comments are uninterpreted plain text, so HTML and other +annotations such as <code>_this_</code> will reproduce <i>verbatim</i> and should +not be used. +Depending on the context, <code>godoc</code> might not even +reformat comments, so make sure they look good straight up: +use correct spelling, punctuation, and sentence structure, +fold long lines, and so on. +</p> + +<p> +Inside a package, any comment immediately preceding a top-level declaration +serves as a <i>doc comment</i> for that declaration. +Every exported (capitalized) name in a program should +have a doc comment. +</p> + +<p> +Doc comments work best as complete sentences, which allow +a wide variety of automated presentations. +The first sentence should be a one-sentence summary that +starts with the name being declared. +</p> + +<pre> +// Compile parses a regular expression and returns, if successful, a Regexp +// object that can be used to match against text. +func Compile(str string) (regexp *Regexp, error os.Error) { +</pre> + +<p> +Go's declaration syntax allows grouping of declarations. +A single doc comment can introduce a group of related constants or variables. +Since the whole declaration is presented, such a comment can often be perfunctory. +</p> + +<pre> +// Error codes returned by failures to parse an expression. +var ( + ErrInternal = os.NewError("regexp: internal error") + ErrUnmatchedLpar = os.NewError("regexp: unmatched '('") + ErrUnmatchedRpar = os.NewError("regexp: unmatched ')'") + ... +) +</pre> + +<p> +Even for private names, grouping can also indicate relationships between items, +such as the fact that a set of variables is protected by a mutex. +</p> + +<pre> +var ( + countLock sync.Mutex + inputCount uint32 + outputCount uint32 + errorCount uint32 +) +</pre> + +<h2 id="names">Names</h2> + +<p> +Names are as important in Go as in any other language. +In some cases they even have semantic effect: for instance, +the visibility of a name outside a package is determined by whether its +first character is upper case. +It's therefore worth spending a little time talking about naming conventions +in Go programs. +</p> + + +<h3 id="package-names">Package names</h3> + +<p> +When a package is imported, the package name becomes an accessor for the +contents. After +</p> + +<pre> +import "bytes" +</pre> + +<p> +the importing package can talk about <code>bytes.Buffer</code>. It's +helpful if everyone using the package can use the same name to refer to +its contents, which implies that the package name should be good: +short, concise, evocative. By convention, packages are given +lower case, single-word names; there should be no need for underscores +or mixedCaps. +Err on the side of brevity, since everyone using your +package will be typing that name. +And don't worry about collisions <i>a priori</i>. +The package name is only the default name for imports; it need not be unique +across all source code, and in the rare case of a collision the +importing package can choose a different name to use locally. +In any case, confusion is rare because the file name in the import +determines just which package is being used. +</p> + +<p> +Another convention is that the package name is the base name of +its source directory; +the package in <code>src/pkg/encoding/base64</code> +is imported as <code>"encoding/base64"</code> but has name <code>base64</code>, +not <code>encoding_base64</code> and not <code>encodingBase64</code>. +</p> + +<p> +The importer of a package will use the name to refer to its contents +(the <code>import .</code> notation is intended mostly for tests and other +unusual situations and should be avoided unless necessary), +so exported names in the package can use that fact +to avoid stutter. +For instance, the buffered reader type in the <code>bufio</code> package is called <code>Reader</code>, +not <code>BufReader</code>, because users see it as <code>bufio.Reader</code>, +which is a clear, concise name. +Moreover, +because imported entities are always addressed with their package name, <code>bufio.Reader</code> +does not conflict with <code>io.Reader</code>. +Similarly, the function to make new instances of <code>ring.Ring</code>—which +is the definition of a <em>constructor</em> in Go—would +normally be called <code>NewRing</code>, but since +<code>Ring</code> is the only type exported by the package, and since the +package is called <code>ring</code>, it's called just <code>New</code>, +which clients of the package see as <code>ring.New</code>. +Use the package structure to help you choose good names. +</p> + +<p> +Another short example is <code>once.Do</code>; +<code>once.Do(setup)</code> reads well and would not be improved by +writing <code>once.DoOrWaitUntilDone(setup)</code>. +Long names don't automatically make things more readable. +If the name represents something intricate or subtle, it's usually better +to write a helpful doc comment than to attempt to put all the information +into the name. +</p> + +<h3 id="Getters">Getters</h3> + +<p> +Go doesn't provide automatic support for getters and setters. +There's nothing wrong with providing getters and setters yourself, +and it's often appropriate to do so, but it's neither idiomatic nor necessary +to put <code>Get</code> into the getter's name. If you have a field called +<code>owner</code> (lower case, unexported), the getter method should be +called <code>Owner</code> (upper case, exported), not <code>GetOwner</code>. +The use of upper-case names for export provides the hook to discriminate +the field from the method. +A setter function, if needed, will likely be called <code>SetOwner</code>. +Both names read well in practice: +</p> +<pre> +owner := obj.Owner() +if owner != user { + obj.SetOwner(user) +} +</pre> + +<h3 id="interface-names">Interface names</h3> + +<p> +By convention, one-method interfaces are named by +the method name plus the -er suffix: <code>Reader</code>, +<code>Writer</code>, <code>Formatter</code> etc. +</p> + +<p> +There are a number of such names and it's productive to honor them and the function +names they capture. +<code>Read</code>, <code>Write</code>, <code>Close</code>, <code>Flush</code>, +<code>String</code> and so on have +canonical signatures and meanings. To avoid confusion, +don't give your method one of those names unless it +has the same signature and meaning. +Conversely, if your type implements a method with the +same meaning as a method on a well-known type, +give it the same name and signature; +call your string-converter method <code>String</code> not <code>ToString</code>. +</p> + +<h3 id="mixed-caps">MixedCaps</h3> + +<p> +Finally, the convention in Go is to use <code>MixedCaps</code> +or <code>mixedCaps</code> rather than underscores to write +multiword names. +</p> + +<h2 id="semicolons">Semicolons</h2> + +<p> +Like C, Go's formal grammar uses semicolons to terminate statements; +unlike C, those semicolons do not appear in the source. +Instead the lexer uses a simple rule to insert semicolons automatically +as it scans, so the input text is mostly free of them. +</p> + +<p> +The rule is this. If the last token before a newline is an identifier +(which includes words like <code>int</code> and <code>float64</code>), +a basic literal such as a number or string constant, or one of the +tokens +</p> +<pre> +break continue fallthrough return ++ -- ) } +</pre> +<p> +the lexer always inserts a semicolon after the token. +This could be summarized as, “if the newline comes +after a token that could end a statement, insert a semicolon”. +</p> + +<p> +A semicolon can also be omitted immediately before a closing brace, +so a statement such as +</p> +<pre> + go func() { for { dst <- <-src } }() +</pre> +<p> +needs no semicolons. +Idiomatic Go programs have semicolons only in places such as +<code>for</code> loop clauses, to separate the initializer, condition, and +continuation elements. They are also necessary to separate multiple +statements on a line, should you write code that way. +</p> + +<p> +One caveat. You should never put the opening brace of a +control structure (<code>if</code>, <code>for</code>, <code>switch</code>, +or <code>select</code>) on the next line. If you do, a semicolon +will be inserted before the brace, which could cause unwanted +effects. Write them like this +</p> + +<pre> +if i < f() { + g() +} +</pre> +<p> +not like this +</p> +<pre> +if i < f() // wrong! +{ // wrong! + g() +} +</pre> + + +<h2 id="control-structures">Control structures</h2> + +<p> +The control structures of Go are related to those of C but differ +in important ways. +There is no <code>do</code> or <code>while</code> loop, only a +slightly generalized +<code>for</code>; +<code>switch</code> is more flexible; +<code>if</code> and <code>switch</code> accept an optional +initialization statement like that of <code>for</code>; +and there are new control structures including a type switch and a +multiway communications multiplexer, <code>select</code>. +The syntax is also slightly different: +there are no parentheses +and the bodies must always be brace-delimited. +</p> + +<h3 id="if">If</h3> + +<p> +In Go a simple <code>if</code> looks like this: +</p> +<pre> +if x > 0 { + return y +} +</pre> + +<p> +Mandatory braces encourage writing simple <code>if</code> statements +on multiple lines. It's good style to do so anyway, +especially when the body contains a control statement such as a +<code>return</code> or <code>break</code>. +</p> + +<p> +Since <code>if</code> and <code>switch</code> accept an initialization +statement, it's common to see one used to set up a local variable. +</p> + +<pre> +if err := file.Chmod(0664); err != nil { + log.Print(err) + return err +} +</pre> + +<p id="else"> +In the Go libraries, you'll find that +when an <code>if</code> statement doesn't flow into the next statement—that is, +the body ends in <code>break</code>, <code>continue</code>, +<code>goto</code>, or <code>return</code>—the unnecessary +<code>else</code> is omitted. +</p> + +<pre> +f, err := os.Open(name) +if err != nil { + return err +} +codeUsing(f) +</pre> + +<p> +This is an example of a common situation where code must guard against a +sequence of error conditions. The code reads well if the +successful flow of control runs down the page, eliminating error cases +as they arise. Since error cases tend to end in <code>return</code> +statements, the resulting code needs no <code>else</code> statements. +</p> + +<pre> +f, err := os.Open(name) +if err != nil { + return err +} +d, err := f.Stat() +if err != nil { + return err +} +codeUsing(f, d) +</pre> + + +<h3 id="for">For</h3> + +<p> +The Go <code>for</code> loop is similar to—but not the same as—C's. +It unifies <code>for</code> +and <code>while</code> and there is no <code>do-while</code>. +There are three forms, only one of which has semicolons. +</p> +<pre> +// Like a C for +for init; condition; post { } + +// Like a C while +for condition { } + +// Like a C for(;;) +for { } +</pre> + +<p> +Short declarations make it easy to declare the index variable right in the loop. +</p> +<pre> +sum := 0 +for i := 0; i < 10; i++ { + sum += i +} +</pre> + +<p> +If you're looping over an array, slice, string, or map, +or reading from a channel, a <code>range</code> clause can +manage the loop. +</p> +<pre> +var m map[string]int +sum := 0 +for _, value := range m { // key is unused + sum += value +} +</pre> + +<p> +For strings, the <code>range</code> does more work for you, breaking out individual +Unicode characters by parsing the UTF-8. +Erroneous encodings consume one byte and produce the +replacement rune U+FFFD. The loop +</p> +<pre> +for pos, char := range "日本語" { + fmt.Printf("character %c starts at byte position %d\n", char, pos) +} +</pre> +<p> +prints +</p> +<pre> +character 日 starts at byte position 0 +character 本 starts at byte position 3 +character 語 starts at byte position 6 +</pre> + +<p> +Finally, Go has no comma operator and <code>++</code> and <code>--</code> +are statements not expressions. +Thus if you want to run multiple variables in a <code>for</code> +you should use parallel assignment. +</p> +<pre> +// Reverse a +for i, j := 0, len(a)-1; i < j; i, j = i+1, j-1 { + a[i], a[j] = a[j], a[i] +} +</pre> + +<h3 id="switch">Switch</h3> + +<p> +Go's <code>switch</code> is more general than C's. +The expressions need not be constants or even integers, +the cases are evaluated top to bottom until a match is found, +and if the <code>switch</code> has no expression it switches on +<code>true</code>. +It's therefore possible—and idiomatic—to write an +<code>if</code>-<code>else</code>-<code>if</code>-<code>else</code> +chain as a <code>switch</code>. +</p> + +<pre> +func unhex(c byte) byte { + switch { + case '0' <= c && c <= '9': + return c - '0' + case 'a' <= c && c <= 'f': + return c - 'a' + 10 + case 'A' <= c && c <= 'F': + return c - 'A' + 10 + } + return 0 +} +</pre> + +<p> +There is no automatic fall through, but cases can be presented +in comma-separated lists. +<pre> +func shouldEscape(c byte) bool { + switch c { + case ' ', '?', '&', '=', '#', '+', '%': + return true + } + return false +} +</pre> + +<p> +Here's a comparison routine for byte arrays that uses two +<code>switch</code> statements: +<pre> +// Compare returns an integer comparing the two byte arrays +// lexicographically. +// The result will be 0 if a == b, -1 if a < b, and +1 if a > b +func Compare(a, b []byte) int { + for i := 0; i < len(a) && i < len(b); i++ { + switch { + case a[i] > b[i]: + return 1 + case a[i] < b[i]: + return -1 + } + } + switch { + case len(a) < len(b): + return -1 + case len(a) > len(b): + return 1 + } + return 0 +} +</pre> + +<p> +A switch can also be used to discover the dynamic type of an interface +variable. Such a <em>type switch</em> uses the syntax of a type +assertion with the keyword <code>type</code> inside the parentheses. +If the switch declares a variable in the expression, the variable will +have the corresponding type in each clause. +</p> +<pre> +switch t := interfaceValue.(type) { +default: + fmt.Printf("unexpected type %T", t) // %T prints type +case bool: + fmt.Printf("boolean %t\n", t) +case int: + fmt.Printf("integer %d\n", t) +case *bool: + fmt.Printf("pointer to boolean %t\n", *t) +case *int: + fmt.Printf("pointer to integer %d\n", *t) +} +</pre> + +<h2 id="functions">Functions</h2> + +<h3 id="multiple-returns">Multiple return values</h3> + +<p> +One of Go's unusual features is that functions and methods +can return multiple values. This form can be used to +improve on a couple of clumsy idioms in C programs: in-band +error returns (such as <code>-1</code> for <code>EOF</code>) +and modifying an argument. +</p> + +<p> +In C, a write error is signaled by a negative count with the +error code secreted away in a volatile location. +In Go, <code>Write</code> +can return a count <i>and</i> an error: “Yes, you wrote some +bytes but not all of them because you filled the device”. +The signature of <code>*File.Write</code> in package <code>os</code> is: +</p> + +<pre> +func (file *File) Write(b []byte) (n int, err Error) +</pre> + +<p> +and as the documentation says, it returns the number of bytes +written and a non-nil <code>Error</code> when <code>n</code> +<code>!=</code> <code>len(b)</code>. +This is a common style; see the section on error handling for more examples. +</p> + +<p> +A similar approach obviates the need to pass a pointer to a return +value to simulate a reference parameter. +Here's a simple-minded function to +grab a number from a position in a byte array, returning the number +and the next position. +</p> + +<pre> +func nextInt(b []byte, i int) (int, int) { + for ; i < len(b) && !isDigit(b[i]); i++ { + } + x := 0 + for ; i < len(b) && isDigit(b[i]); i++ { + x = x*10 + int(b[i])-'0' + } + return x, i +} +</pre> + +<p> +You could use it to scan the numbers in an input array <code>a</code> like this: +</p> + +<pre> + for i := 0; i < len(a); { + x, i = nextInt(a, i) + fmt.Println(x) + } +</pre> + +<h3 id="named-results">Named result parameters</h3> + +<p> +The return or result "parameters" of a Go function can be given names and +used as regular variables, just like the incoming parameters. +When named, they are initialized to the zero values for their types when +the function begins; if the function executes a <code>return</code> statement +with no arguments, the current values of the result parameters are +used as the returned values. +</p> + +<p> +The names are not mandatory but they can make code shorter and clearer: +they're documentation. +If we name the results of <code>nextInt</code> it becomes +obvious which returned <code>int</code> +is which. +</p> + +<pre> +func nextInt(b []byte, pos int) (value, nextPos int) { +</pre> + +<p> +Because named results are initialized and tied to an unadorned return, they can simplify +as well as clarify. Here's a version +of <code>io.ReadFull</code> that uses them well: +</p> + +<pre> +func ReadFull(r Reader, buf []byte) (n int, err os.Error) { + for len(buf) > 0 && err == nil { + var nr int + nr, err = r.Read(buf) + n += nr + buf = buf[nr:len(buf)] + } + return +} +</pre> + +<h3 id="defer">Defer</h3> + +<p> +Go's <code>defer</code> statement schedules a function call (the +<i>deferred</i> function) to be run immediately before the function +executing the <code>defer</code> returns. It's an unusual but +effective way to deal with situations such as resources that must be +released regardless of which path a function takes to return. The +canonical examples are unlocking a mutex or closing a file. +</p> + +<pre> +// Contents returns the file's contents as a string. +func Contents(filename string) (string, os.Error) { + f, err := os.Open(filename) + if err != nil { + return "", err + } + defer f.Close() // f.Close will run when we're finished. + + var result []byte + buf := make([]byte, 100) + for { + n, err := f.Read(buf[0:]) + result = append(result, buf[0:n]...) // append is discussed later. + if err != nil { + if err == os.EOF { + break + } + return "", err // f will be closed if we return here. + } + } + return string(result), nil // f will be closed if we return here. +} +</pre> + +<p> +Deferring a call to a function such as <code>Close</code> has two advantages. First, it +guarantees that you will never forget to close the file, a mistake +that's easy to make if you later edit the function to add a new return +path. Second, it means that the close sits near the open, +which is much clearer than placing it at the end of the function. +</p> + +<p> +The arguments to the deferred function (which include the receiver if +the function is a method) are evaluated when the <i>defer</i> +executes, not when the <i>call</i> executes. Besides avoiding worries +about variables changing values as the function executes, this means +that a single deferred call site can defer multiple function +executions. Here's a silly example. +</p> + +<pre> +for i := 0; i < 5; i++ { + defer fmt.Printf("%d ", i) +} +</pre> + +<p> +Deferred functions are executed in LIFO order, so this code will cause +<code>4 3 2 1 0</code> to be printed when the function returns. A +more plausible example is a simple way to trace function execution +through the program. We could write a couple of simple tracing +routines like this: +</p> + +<pre> +func trace(s string) { fmt.Println("entering:", s) } +func untrace(s string) { fmt.Println("leaving:", s) } + +// Use them like this: +func a() { + trace("a") + defer untrace("a") + // do something.... +} +</pre> + +<p> +We can do better by exploiting the fact that arguments to deferred +functions are evaluated when the <code>defer</code> executes. The +tracing routine can set up the argument to the untracing routine. +This example: +</p> + +<pre> +func trace(s string) string { + fmt.Println("entering:", s) + return s +} + +func un(s string) { + fmt.Println("leaving:", s) +} + +func a() { + defer un(trace("a")) + fmt.Println("in a") +} + +func b() { + defer un(trace("b")) + fmt.Println("in b") + a() +} + +func main() { + b() +} +</pre> + +<p> +prints +</p> + +<pre> +entering: b +in b +entering: a +in a +leaving: a +leaving: b +</pre> + +<p> +For programmers accustomed to block-level resource management from +other languages, <code>defer</code> may seem peculiar, but its most +interesting and powerful applications come precisely from the fact +that it's not block-based but function-based. In the section on +<code>panic</code> and <code>recover</code> we'll see another +example of its possibilities. +</p> + +<h2 id="data">Data</h2> + +<h3 id="allocation_new">Allocation with <code>new</code></h3> + +<p> +Go has two allocation primitives, the built-in functions +<code>new</code> and <code>make</code>. +They do different things and apply to different types, which can be confusing, +but the rules are simple. +Let's talk about <code>new</code> first. +It's a built-in function that allocates memory, but unlike its namesakes +in some other languages it does not <em>initialize</em> the memory, +it only <em>zeroes</em> it. +That is, +<code>new(T)</code> allocates zeroed storage for a new item of type +<code>T</code> and returns its address, a value of type <code>*T</code>. +In Go terminology, it returns a pointer to a newly allocated zero value of type +<code>T</code>. +</p> + +<p> +Since the memory returned by <code>new</code> is zeroed, it's helpful to arrange that the +zeroed object can be used without further initialization. This means a user of +the data structure can create one with <code>new</code> and get right to +work. +For example, the documentation for <code>bytes.Buffer</code> states that +"the zero value for <code>Buffer</code> is an empty buffer ready to use." +Similarly, <code>sync.Mutex</code> does not +have an explicit constructor or <code>Init</code> method. +Instead, the zero value for a <code>sync.Mutex</code> +is defined to be an unlocked mutex. +</p> + +<p> +The zero-value-is-useful property works transitively. Consider this type declaration. +</p> + +<pre> +type SyncedBuffer struct { + lock sync.Mutex + buffer bytes.Buffer +} +</pre> + +<p> +Values of type <code>SyncedBuffer</code> are also ready to use immediately upon allocation +or just declaration. In the next snippet, both <code>p</code> and <code>v</code> will work +correctly without further arrangement. +</p> + +<pre> +p := new(SyncedBuffer) // type *SyncedBuffer +var v SyncedBuffer // type SyncedBuffer +</pre> + +<h3 id="composite_literals">Constructors and composite literals</h3> + +<p> +Sometimes the zero value isn't good enough and an initializing +constructor is necessary, as in this example derived from +package <code>os</code>. +</p> + +<pre> +func NewFile(fd int, name string) *File { + if fd < 0 { + return nil + } + f := new(File) + f.fd = fd + f.name = name + f.dirinfo = nil + f.nepipe = 0 + return f +} +</pre> + +<p> +There's a lot of boiler plate in there. We can simplify it +using a <i>composite literal</i>, which is +an expression that creates a +new instance each time it is evaluated. +</p> + +<pre> +func NewFile(fd int, name string) *File { + if fd < 0 { + return nil + } + f := File{fd, name, nil, 0} + return &f +} +</pre> + +<p> +Note that, unlike in C, it's perfectly OK to return the address of a local variable; +the storage associated with the variable survives after the function +returns. +In fact, taking the address of a composite literal +allocates a fresh instance each time it is evaluated, +so we can combine these last two lines. +</p> + +<pre> + return &File{fd, name, nil, 0} +</pre> + +<p> +The fields of a composite literal are laid out in order and must all be present. +However, by labeling the elements explicitly as <i>field</i><code>:</code><i>value</i> +pairs, the initializers can appear in any +order, with the missing ones left as their respective zero values. Thus we could say +</p> + +<pre> + return &File{fd: fd, name: name} +</pre> + +<p> +As a limiting case, if a composite literal contains no fields at all, it creates +a zero value for the type. The expressions <code>new(File)</code> and <code>&File{}</code> are equivalent. +</p> + +<p> +Composite literals can also be created for arrays, slices, and maps, +with the field labels being indices or map keys as appropriate. +In these examples, the initializations work regardless of the values of <code>Enone</code>, +<code>Eio</code>, and <code>Einval</code>, as long as they are distinct. +</p> + +<pre> +a := [...]string {Enone: "no error", Eio: "Eio", Einval: "invalid argument"} +s := []string {Enone: "no error", Eio: "Eio", Einval: "invalid argument"} +m := map[int]string{Enone: "no error", Eio: "Eio", Einval: "invalid argument"} +</pre> + +<h3 id="allocation_make">Allocation with <code>make</code></h3> + +<p> +Back to allocation. +The built-in function <code>make(T, </code><i>args</i><code>)</code> serves +a purpose different from <code>new(T)</code>. +It creates slices, maps, and channels only, and it returns an initialized (not zero) +value of type <code>T</code>, not <code>*T</code>. +The reason for the distinction +is that these three types are, under the covers, references to data structures that +must be initialized before use. +A slice, for example, is a three-item descriptor +containing a pointer to the data (inside an array), the length, and the +capacity, and until those items are initialized, the slice is <code>nil</code>. +For slices, maps, and channels, +<code>make</code> initializes the internal data structure and prepares +the value for use. +For instance, +</p> + +<pre> +make([]int, 10, 100) +</pre> + +<p> +allocates an array of 100 ints and then creates a slice +structure with length 10 and a capacity of 100 pointing at the first +10 elements of the array. +(When making a slice, the capacity can be omitted; see the section on slices +for more information.) +In contrast, <code>new([]int)</code> returns a pointer to a newly allocated, zeroed slice +structure, that is, a pointer to a <code>nil</code> slice value. + +<p> +These examples illustrate the difference between <code>new</code> and +<code>make</code>. +</p> + +<pre> +var p *[]int = new([]int) // allocates slice structure; *p == nil; rarely useful +var v []int = make([]int, 100) // the slice v now refers to a new array of 100 ints + +// Unnecessarily complex: +var p *[]int = new([]int) +*p = make([]int, 100, 100) + +// Idiomatic: +v := make([]int, 100) +</pre> + +<p> +Remember that <code>make</code> applies only to maps, slices and channels +and does not return a pointer. +To obtain an explicit pointer allocate with <code>new</code>. +</p> + +<h3 id="arrays">Arrays</h3> + +<p> +Arrays are useful when planning the detailed layout of memory and sometimes +can help avoid allocation, but primarily +they are a building block for slices, the subject of the next section. +To lay the foundation for that topic, here are a few words about arrays. +</p> + +<p> +There are major differences between the ways arrays work in Go and C. +In Go, +</p> +<ul> +<li> +Arrays are values. Assigning one array to another copies all the elements. +</li> +<li> +In particular, if you pass an array to a function, it +will receive a <i>copy</i> of the array, not a pointer to it. +<li> +The size of an array is part of its type. The types <code>[10]int</code> +and <code>[20]int</code> are distinct. +</li> +</ul> + +<p> +The value property can be useful but also expensive; if you want C-like behavior and efficiency, +you can pass a pointer to the array. +</p> + +<pre> +func Sum(a *[3]float64) (sum float64) { + for _, v := range *a { + sum += v + } + return +} + +array := [...]float64{7.0, 8.5, 9.1} +x := Sum(&array) // Note the explicit address-of operator +</pre> + +<p> +But even this style isn't idiomatic Go. Slices are. +</p> + +<h3 id="slices">Slices</h3> + +<p> +Slices wrap arrays to give a more general, powerful, and convenient +interface to sequences of data. Except for items with explicit +dimension such as transformation matrices, most array programming in +Go is done with slices rather than simple arrays. +</p> +<p> +Slices are <i>reference types</i>, which means that if you assign one +slice to another, both refer to the same underlying array. For +instance, if a function takes a slice argument, changes it makes to +the elements of the slice will be visible to the caller, analogous to +passing a pointer to the underlying array. A <code>Read</code> +function can therefore accept a slice argument rather than a pointer +and a count; the length within the slice sets an upper +limit of how much data to read. Here is the signature of the +<code>Read</code> method of the <code>File</code> type in package +<code>os</code>: +</p> +<pre> +func (file *File) Read(buf []byte) (n int, err os.Error) +</pre> +<p> +The method returns the number of bytes read and an error value, if +any. To read into the first 32 bytes of a larger buffer +<code>b</code>, <i>slice</i> (here used as a verb) the buffer. +</p> +<pre> + n, err := f.Read(buf[0:32]) +</pre> +<p> +Such slicing is common and efficient. In fact, leaving efficiency aside for +the moment, this snippet would also read the first 32 bytes of the buffer. +</p> +<pre> + var n int + var err os.Error + for i := 0; i < 32; i++ { + nbytes, e := f.Read(buf[i:i+1]) // Read one byte. + if nbytes == 0 || e != nil { + err = e + break + } + n += nbytes + } +</pre> +<p> +The length of a slice may be changed as long as it still fits within +the limits of the underlying array; just assign it to a slice of +itself. The <i>capacity</i> of a slice, accessible by the built-in +function <code>cap</code>, reports the maximum length the slice may +assume. Here is a function to append data to a slice. If the data +exceeds the capacity, the slice is reallocated. The +resulting slice is returned. The function uses the fact that +<code>len</code> and <code>cap</code> are legal when applied to the +<code>nil</code> slice, and return 0. +</p> +<pre> +func Append(slice, data[]byte) []byte { + l := len(slice) + if l + len(data) > cap(slice) { // reallocate + // Allocate double what's needed, for future growth. + newSlice := make([]byte, (l+len(data))*2) + // The copy function is predeclared and works for any slice type. + copy(newSlice, slice) + slice = newSlice + } + slice = slice[0:l+len(data)] + for i, c := range data { + slice[l+i] = c + } + return slice +} +</pre> +<p> +We must return the slice afterwards because, although <code>Append</code> +can modify the elements of <code>slice</code>, the slice itself (the run-time data +structure holding the pointer, length, and capacity) is passed by value. +<p> +The idea of appending to a slice is so useful it's captured by the +<code>append</code> built-in function. To understand that function's +design, though, we need a little more information, so we'll return +to it later. +</p> + + +<h3 id="maps">Maps</h3> + +<p> +Maps are a convenient and powerful built-in data structure to associate +values of different types. +The key can be of any type for which the equality operator is defined, +such as integers, +floating point and complex numbers, +strings, pointers, and interfaces (as long as the dynamic type +supports equality). Structs, arrays and slices cannot be used as map keys, +because equality is not defined on those types. +Like slices, maps are a reference type. If you pass a map to a function +that changes the contents of the map, the changes will be visible +in the caller. +</p> +<p> +Maps can be constructed using the usual composite literal syntax +with colon-separated key-value pairs, +so it's easy to build them during initialization. +</p> +<pre> +var timeZone = map[string] int { + "UTC": 0*60*60, + "EST": -5*60*60, + "CST": -6*60*60, + "MST": -7*60*60, + "PST": -8*60*60, +} +</pre> +<p> +Assigning and fetching map values looks syntactically just like +doing the same for arrays except that the index doesn't need to +be an integer. +</p> +<pre> +offset := timeZone["EST"] +</pre> +<p> +An attempt to fetch a map value with a key that +is not present in the map will return the zero value for the type +of the entries +in the map. For instance, if the map contains integers, looking +up a non-existent key will return <code>0</code>. +A set can be implemented as a map with value type <code>bool</code>. +Set the map entry to <code>true</code> to put the value in the set, and then +test it by simple indexing. +</p> +<pre> +attended := map[string] bool { + "Ann": true, + "Joe": true, + ... +} + +if attended[person] { // will be false if person is not in the map + fmt.Println(person, "was at the meeting") +} +</pre> +<p> +Sometimes you need to distinguish a missing entry from +a zero value. Is there an entry for <code>"UTC"</code> +or is that zero value because it's not in the map at all? +You can discriminate with a form of multiple assignment. +</p> +<pre> +var seconds int +var ok bool +seconds, ok = timeZone[tz] +</pre> +<p> +For obvious reasons this is called the “comma ok” idiom. +In this example, if <code>tz</code> is present, <code>seconds</code> +will be set appropriately and <code>ok</code> will be true; if not, +<code>seconds</code> will be set to zero and <code>ok</code> will +be false. +Here's a function that puts it together with a nice error report: +</p> +<pre> +func offset(tz string) int { + if seconds, ok := timeZone[tz]; ok { + return seconds + } + log.Println("unknown time zone:", tz) + return 0 +} +</pre> +<p> +To test for presence in the map without worrying about the actual value, +you can use the <em>blank identifier</em>, a simple underscore (<code>_</code>). +The blank identifier can be assigned or declared with any value of any type, with the +value discarded harmlessly. For testing just presence in a map, use the blank +identifier in place of the usual variable for the value. +</p> +<pre> +_, present := timeZone[tz] +</pre> +<p> +To delete a map entry, turn the multiple assignment around by placing +an extra boolean on the right; if the boolean is false, the entry +is deleted. It's safe to do this even if the key is already absent +from the map. +</p> +<pre> +timeZone["PDT"] = 0, false // Now on Standard Time +</pre> + +<h3 id="printing">Printing</h3> + +<p> +Formatted printing in Go uses a style similar to C's <code>printf</code> +family but is richer and more general. The functions live in the <code>fmt</code> +package and have capitalized names: <code>fmt.Printf</code>, <code>fmt.Fprintf</code>, +<code>fmt.Sprintf</code> and so on. The string functions (<code>Sprintf</code> etc.) +return a string rather than filling in a provided buffer. +</p> +<p> +You don't need to provide a format string. For each of <code>Printf</code>, +<code>Fprintf</code> and <code>Sprintf</code> there is another pair +of functions, for instance <code>Print</code> and <code>Println</code>. +These functions do not take a format string but instead generate a default +format for each argument. The <code>Println</code> versions also insert a blank +between arguments and append a newline to the output while +the <code>Print</code> versions add blanks only if the operand on neither side is a string. +In this example each line produces the same output. +</p> +<pre> +fmt.Printf("Hello %d\n", 23) +fmt.Fprint(os.Stdout, "Hello ", 23, "\n") +fmt.Println("Hello", 23) +fmt.Println(fmt.Sprint("Hello ", 23)) +</pre> +<p> +As mentioned in +the <a href="go_tutorial.html">tutorial</a>, <code>fmt.Fprint</code> +and friends take as a first argument any object +that implements the <code>io.Writer</code> interface; the variables <code>os.Stdout</code> +and <code>os.Stderr</code> are familiar instances. +</p> +<p> +Here things start to diverge from C. First, the numeric formats such as <code>%d</code> +do not take flags for signedness or size; instead, the printing routines use the +type of the argument to decide these properties. +</p> +<pre> +var x uint64 = 1<<64 - 1 +fmt.Printf("%d %x; %d %x\n", x, x, int64(x), int64(x)) +</pre> +<p> +prints +</p> +<pre> +18446744073709551615 ffffffffffffffff; -1 -1 +</pre> +<p> +If you just want the default conversion, such as decimal for integers, you can use +the catchall format <code>%v</code> (for “value”); the result is exactly +what <code>Print</code> and <code>Println</code> would produce. +Moreover, that format can print <em>any</em> value, even arrays, structs, and +maps. Here is a print statement for the time zone map defined in the previous section. +</p> +<pre> +fmt.Printf("%v\n", timeZone) // or just fmt.Println(timeZone) +</pre> +<p> +which gives output +</p> +<pre> +map[CST:-21600 PST:-28800 EST:-18000 UTC:0 MST:-25200] +</pre> +<p> +For maps the keys may be output in any order, of course. +When printing a struct, the modified format <code>%+v</code> annotates the +fields of the structure with their names, and for any value the alternate +format <code>%#v</code> prints the value in full Go syntax. +</p> +<pre> +type T struct { + a int + b float + c string +} +t := &T{ 7, -2.35, "abc\tdef" } +fmt.Printf("%v\n", t) +fmt.Printf("%+v\n", t) +fmt.Printf("%#v\n", t) +fmt.Printf("%#v\n", timeZone) +</pre> +<p> +prints +</p> +<pre> +&{7 -2.35 abc def} +&{a:7 b:-2.35 c:abc def} +&main.T{a:7, b:-2.35, c:"abc\tdef"} +map[string] int{"CST":-21600, "PST":-28800, "EST":-18000, "UTC":0, "MST":-25200} +</pre> +<p> +(Note the ampersands.) +That quoted string format is also available through <code>%q</code> when +applied to a value of type <code>string</code> or <code>[]byte</code>; +the alternate format <code>%#q</code> will use backquotes instead if possible. +Also, <code>%x</code> works on strings and arrays of bytes as well as on integers, +generating a long hexadecimal string, and with +a space in the format (<code>% x</code>) it puts spaces between the bytes. +</p> +<p> +Another handy format is <code>%T</code>, which prints the <em>type</em> of a value. +<pre> +fmt.Printf("%T\n", timeZone) +</pre> +<p> +prints +</p> +<pre> +map[string] int +</pre> +<p> +If you want to control the default format for a custom type, all that's required is to define +a method with the signature <code>String() string</code> on the type. +For our simple type <code>T</code>, that might look like this. +</p> +<pre> +func (t *T) String() string { + return fmt.Sprintf("%d/%g/%q", t.a, t.b, t.c) +} +fmt.Printf("%v\n", t) +</pre> +<p> +to print in the format +</p> +<pre> +7/-2.35/"abc\tdef" +</pre> +<p> +(If you need to print <em>values</em> of type <code>T</code> as well as pointers to <code>T</code>, +the receiver for <code>String</code> must be of value type; this example used a pointer because +that's more efficient and idiomatic for struct types. +See the section below on <a href="#pointers_vs_values">pointers vs. value receivers</a> for more information.) +</p> +<p> +Our <code>String</code> method is able to call <code>Sprintf</code> because the +print routines are fully reentrant and can be used recursively. +We can even go one step further and pass a print routine's arguments directly to another such routine. +The signature of <code>Printf</code> uses the type <code>...interface{}</code> +for its final argument to specify that an arbitrary number of parameters (of arbitrary type) +can appear after the format. +</p> +<pre> +func Printf(format string, v ...interface{}) (n int, errno os.Error) { +</pre> +<p> +Within the function <code>Printf</code>, <code>v</code> acts like a variable of type +<code>[]interface{}</code> but if it is passed to another variadic function, it acts like +a regular list of arguments. +Here is the implementation of the +function <code>log.Println</code> we used above. It passes its arguments directly to +<code>fmt.Sprintln</code> for the actual formatting. +</p> +<pre> +// Println prints to the standard logger in the manner of fmt.Println. +func Println(v ...interface{}) { + std.Output(2, fmt.Sprintln(v...)) // Output takes parameters (int, string) +} +</pre> +<p> +We write <code>...</code> after <code>v</code> in the nested call to <code>Sprintln</code> to tell the +compiler to treat <code>v</code> as a list of arguments; otherwise it would just pass +<code>v</code> as a single slice argument. +<p> +There's even more to printing than we've covered here. See the <code>godoc</code> documentation +for package <code>fmt</code> for the details. +</p> +<p> +By the way, a <code>...</code> parameter can be of a specific type, for instance <code>...int</code> +for a min function that chooses the least of a list of integers: +</p> +<pre> +func Min(a ...int) int { + min := int(^uint(0) >> 1) // largest int + for _, i := range a { + if i < min { + min = i + } + } + return min +} +</pre> + +<h3 id="append">Append</h3> +<p> +Now we have the missing piece we needed to explain the design of +the <code>append</code> built-in function. The signature of <code>append</code> +is different from our custom <code>Append</code> function above. +Schematically, it's like this: +<pre> +func append(slice []<i>T</i>, elements...T) []<i>T</i> +</pre> +where <i>T</i> is a placeholder for any given type. You can't +actually write a function in Go where the type <code>T</code> +is determined by the caller. +That's why <code>append</code> is built in: it needs support from the +compiler. +<p> +What <code>append</code> does is append the elements to the end of +the slice and return the result. The result needs to be returned +because, as with our hand-written <code>Append</code>, the underlying +array may change. This simple example +<pre> +x := []int{1,2,3} +x = append(x, 4, 5, 6) +fmt.Println(x) +</pre> +prints <code>[1 2 3 4 5 6]</code>. So <code>append</code> works a +little like <code>Printf</code>, collecting an arbitrary number of +arguments. +<p> +But what if we wanted to do what our <code>Append</code> does and +append a slice to a slice? Easy: use <code>...</code> at the call +site, just as we did in the call to <code>Output</code> above. This +snippet produces identical output to the one above. +<pre> +x := []int{1,2,3} +y := []int{4,5,6} +x = append(x, y...) +fmt.Println(x) +</pre> +Without that <code>...</code>, it wouldn't compile because the types +would be wrong; <code>y</code> is not of type <code>int</code>. + +<h2 id="initialization">Initialization</h2> + +<p> +Although it doesn't look superficially very different from +initialization in C or C++, initialization in Go is more powerful. +Complex structures can be built during initialization and the ordering +issues between initialized objects in different packages are handled +correctly. +</p> + +<h3 id="constants">Constants</h3> + +<p> +Constants in Go are just that—constant. +They are created at compile time, even when defined as +locals in functions, +and can only be numbers, strings or booleans. +Because of the compile-time restriction, the expressions +that define them must be constant expressions, +evaluatable by the compiler. For instance, +<code>1<<3</code> is a constant expression, while +<code>math.Sin(math.Pi/4)</code> is not because +the function call to <code>math.Sin</code> needs +to happen at run time. +</p> + +<p> +In Go, enumerated constants are created using the <code>iota</code> +enumerator. Since <code>iota</code> can be part of an expression and +expressions can be implicitly repeated, it is easy to build intricate +sets of values. +</p> +<pre> +type ByteSize float64 +const ( + _ = iota // ignore first value by assigning to blank identifier + KB ByteSize = 1<<(10*iota) + MB + GB + TB + PB + EB + ZB + YB +) +</pre> +<p> +The ability to attach a method such as <code>String</code> to a +type makes it possible for such values to format themselves +automatically for printing, even as part of a general type. +</p> +<pre> +func (b ByteSize) String() string { + switch { + case b >= YB: + return fmt.Sprintf("%.2fYB", float64(b/YB)) + case b >= ZB: + return fmt.Sprintf("%.2fZB", float64(b/ZB)) + case b >= EB: + return fmt.Sprintf("%.2fEB", float64(b/EB)) + case b >= PB: + return fmt.Sprintf("%.2fPB", float64(b/PB)) + case b >= TB: + return fmt.Sprintf("%.2fTB", float64(b/TB)) + case b >= GB: + return fmt.Sprintf("%.2fGB", float64(b/GB)) + case b >= MB: + return fmt.Sprintf("%.2fMB", float64(b/MB)) + case b >= KB: + return fmt.Sprintf("%.2fKB", float64(b/KB)) + } + return fmt.Sprintf("%.2fB", float64(b)) +} +</pre> +<p> +(The <code>float64</code> conversions prevent <code>Sprintf</code> +from recurring back through the <code>String</code> method for +<code>ByteSize</code>.) +The expression <code>YB</code> prints as <code>1.00YB</code>, +while <code>ByteSize(1e13)</code> prints as <code>9.09TB</code>. +</p> + +<h3 id="variables">Variables</h3> + +<p> +Variables can be initialized just like constants but the +initializer can be a general expression computed at run time. +</p> +<pre> +var ( + HOME = os.Getenv("HOME") + USER = os.Getenv("USER") + GOROOT = os.Getenv("GOROOT") +) +</pre> + +<h3 id="init">The init function</h3> + +<p> +Finally, each source file can define its own niladic <code>init</code> function to +set up whatever state is required. (Actually each file can have multiple +<code>init</code> functions.) The only restriction is that, although +goroutines can be launched during initialization, they will not begin +execution until it completes; initialization always runs as a single thread +of execution. +And finally means finally: <code>init</code> is called after all the +variable declarations in the package have evaluated their initializers, +and those are evaluated only after all the imported packages have been +initialized. +</p> +<p> +Besides initializations that cannot be expressed as declarations, +a common use of <code>init</code> functions is to verify or repair +correctness of the program state before real execution begins. +</p> + +<pre> +func init() { + if USER == "" { + log.Fatal("$USER not set") + } + if HOME == "" { + HOME = "/usr/" + USER + } + if GOROOT == "" { + GOROOT = HOME + "/go" + } + // GOROOT may be overridden by --goroot flag on command line. + flag.StringVar(&GOROOT, "goroot", GOROOT, "Go root directory") +} +</pre> + +<h2 id="methods">Methods</h2> + +<h3 id="pointers_vs_values">Pointers vs. Values</h3> +<p> +Methods can be defined for any named type that is not a pointer or an interface; +the receiver does not have to be a struct. +<p> +In the discussion of slices above, we wrote an <code>Append</code> +function. We can define it as a method on slices instead. To do +this, we first declare a named type to which we can bind the method, and +then make the receiver for the method a value of that type. +</p> +<pre> +type ByteSlice []byte + +func (slice ByteSlice) Append(data []byte) []byte { + // Body exactly the same as above +} +</pre> +<p> +This still requires the method to return the updated slice. We can +eliminate that clumsiness by redefining the method to take a +<i>pointer</i> to a <code>ByteSlice</code> as its receiver, so the +method can overwrite the caller's slice. +</p> +<pre> +func (p *ByteSlice) Append(data []byte) { + slice := *p + // Body as above, without the return. + *p = slice +} +</pre> +<p> +In fact, we can do even better. If we modify our function so it looks +like a standard <code>Write</code> method, like this, +</p> +<pre> +func (p *ByteSlice) Write(data []byte) (n int, err os.Error) { + slice := *p + // Again as above. + *p = slice + return len(data), nil +} +</pre> +<p> +then the type <code>*ByteSlice</code> satisfies the standard interface +<code>io.Writer</code>, which is handy. For instance, we can +print into one. +</p> +<pre> + var b ByteSlice + fmt.Fprintf(&b, "This hour has %d days\n", 7) +</pre> +<p> +We pass the address of a <code>ByteSlice</code> +because only <code>*ByteSlice</code> satisfies <code>io.Writer</code>. +The rule about pointers vs. values for receivers is that value methods +can be invoked on pointers and values, but pointer methods can only be +invoked on pointers. This is because pointer methods can modify the +receiver; invoking them on a copy of the value would cause those +modifications to be discarded. +</p> +<p> +By the way, the idea of using <code>Write</code> on a slice of bytes +is implemented by <code>bytes.Buffer</code>. +</p> + +<h2 id="interfaces_and_types">Interfaces and other types</h2> + +<h3 id="interfaces">Interfaces</h3> +<p> +Interfaces in Go provide a way to specify the behavior of an +object: if something can do <em>this</em>, then it can be used +<em>here</em>. We've seen a couple of simple examples already; +custom printers can be implemented by a <code>String</code> method +while <code>Fprintf</code> can generate output to anything +with a <code>Write</code> method. +Interfaces with only one or two methods are common in Go code, and are +usually given a name derived from the method, such as <code>io.Writer</code> +for something that implements <code>Write</code>. +</p> +<p> +A type can implement multiple interfaces. +For instance, a collection can be sorted +by the routines in package <code>sort</code> if it implements +<code>sort.Interface</code>, which contains <code>Len()</code>, +<code>Less(i, j int) bool</code>, and <code>Swap(i, j int)</code>, +and it could also have a custom formatter. +In this contrived example <code>Sequence</code> satisfies both. +</p> +<pre> +type Sequence []int + +// Methods required by sort.Interface. +func (s Sequence) Len() int { + return len(s) +} +func (s Sequence) Less(i, j int) bool { + return s[i] < s[j] +} +func (s Sequence) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} + +// Method for printing - sorts the elements before printing. +func (s Sequence) String() string { + sort.Sort(s) + str := "[" + for i, elem := range s { + if i > 0 { + str += " " + } + str += fmt.Sprint(elem) + } + return str + "]" +} +</pre> + +<h3 id="conversions">Conversions</h3> + +<p> +The <code>String</code> method of <code>Sequence</code> is recreating the +work that <code>Sprint</code> already does for slices. We can share the +effort if we convert the <code>Sequence</code> to a plain +<code>[]int</code> before calling <code>Sprint</code>. +</p> +<pre> +func (s Sequence) String() string { + sort.Sort(s) + return fmt.Sprint([]int(s)) +} +</pre> +<p> +The conversion causes <code>s</code> to be treated as an ordinary slice +and therefore receive the default formatting. +Without the conversion, <code>Sprint</code> would find the +<code>String</code> method of <code>Sequence</code> and recur indefinitely. +Because the two types (<code>Sequence</code> and <code>[]int</code>) +are the same if we ignore the type name, it's legal to convert between them. +The conversion doesn't create a new value, it just temporarily acts +as though the existing value has a new type. +(There are other legal conversions, such as from integer to floating point, that +do create a new value.) +</p> +<p> +It's an idiom in Go programs to convert the +type of an expression to access a different +set of methods. As an example, we could use the existing +type <code>sort.IntArray</code> to reduce the entire example +to this: +</p> +<pre> +type Sequence []int + +// Method for printing - sorts the elements before printing +func (s Sequence) String() string { + sort.IntArray(s).Sort() + return fmt.Sprint([]int(s)) +} +</pre> +<p> +Now, instead of having <code>Sequence</code> implement multiple +interfaces (sorting and printing), we're using the ability of a data item to be +converted to multiple types (<code>Sequence</code>, <code>sort.IntArray</code> +and <code>[]int</code>), each of which does some part of the job. +That's more unusual in practice but can be effective. +</p> + +<h3 id="generality">Generality</h3> +<p> +If a type exists only to implement an interface +and has no exported methods beyond that interface, +there is no need to export the type itself. +Exporting just the interface makes it clear that +it's the behavior that matters, not the implementation, +and that other implementations with different properties +can mirror the behavior of the original type. +It also avoids the need to repeat the documentation +on every instance of a common method. +</p> +<p> +In such cases, the constructor should return an interface value +rather than the implementing type. +As an example, in the hash libraries +both <code>crc32.NewIEEE</code> and <code>adler32.New</code> +return the interface type <code>hash.Hash32</code>. +Substituting the CRC-32 algorithm for Adler-32 in a Go program +requires only changing the constructor call; +the rest of the code is unaffected by the change of algorithm. +</p> +<p> +A similar approach allows the streaming cipher algorithms +in the <code>crypto/block</code> package to be +separated from the block ciphers they chain together. +By analogy with the <code>bufio</code> package, +they wrap a <code>Cipher</code> interface +and return <code>hash.Hash</code>, +<code>io.Reader</code>, or <code>io.Writer</code> +interface values, not specific implementations. +</p> +<p> +The interface to <code>crypto/block</code> includes: +</p> +<pre> +type Cipher interface { + BlockSize() int + Encrypt(src, dst []byte) + Decrypt(src, dst []byte) +} + +// NewECBDecrypter returns a reader that reads data +// from r and decrypts it using c in electronic codebook (ECB) mode. +func NewECBDecrypter(c Cipher, r io.Reader) io.Reader + +// NewCBCDecrypter returns a reader that reads data +// from r and decrypts it using c in cipher block chaining (CBC) mode +// with the initialization vector iv. +func NewCBCDecrypter(c Cipher, iv []byte, r io.Reader) io.Reader +</pre> +<p> +<code>NewECBDecrypter</code> and <code>NewCBCReader</code> apply not +just to one specific encryption algorithm and data source but to any +implementation of the <code>Cipher</code> interface and any +<code>io.Reader</code>. Because they return <code>io.Reader</code> +interface values, replacing ECB +encryption with CBC encryption is a localized change. The constructor +calls must be edited, but because the surrounding code must treat the result only +as an <code>io.Reader</code>, it won't notice the difference. +</p> + +<h3 id="interface_methods">Interfaces and methods</h3> +<p> +Since almost anything can have methods attached, almost anything can +satisfy an interface. One illustrative example is in the <code>http</code> +package, which defines the <code>Handler</code> interface. Any object +that implements <code>Handler</code> can serve HTTP requests. +</p> +<pre> +type Handler interface { + ServeHTTP(ResponseWriter, *Request) +} +</pre> +<p> +<code>ResponseWriter</code> is itself an interface that provides access +to the methods needed to return the response to the client. +Those methods include the standard <code>Write</code> method, so an +<code>http.ResponseWriter</code> can be used wherever an <code>io.Writer</code> +can be used. +<code>Request</code> is a struct containing a parsed representation +of the request from the client. +<p> +For brevity, let's ignore POSTs and assume HTTP requests are always +GETs; that simplification does not affect the way the handlers are +set up. Here's a trivial but complete implementation of a handler to +count the number of times the +page is visited. +</p> +<pre> +// Simple counter server. +type Counter struct { + n int +} + +func (ctr *Counter) ServeHTTP(w http.ResponseWriter, req *http.Request) { + ctr.n++ + fmt.Fprintf(w, "counter = %d\n", ctr.n) +} +</pre> +<p> +(Keeping with our theme, note how <code>Fprintf</code> can print to an +<code>http.ResponseWriter</code>.) +For reference, here's how to attach such a server to a node on the URL tree. +<pre> +import "http" +... +ctr := new(Counter) +http.Handle("/counter", ctr) +</pre> +<p> +But why make <code>Counter</code> a struct? An integer is all that's needed. +(The receiver needs to be a pointer so the increment is visible to the caller.) +</p> +<pre> +// Simpler counter server. +type Counter int + +func (ctr *Counter) ServeHTTP(w http.ResponseWriter, req *http.Request) { + *ctr++ + fmt.Fprintf(w, "counter = %d\n", *ctr) +} +</pre> +<p> +What if your program has some internal state that needs to be notified that a page +has been visited? Tie a channel to the web page. +</p> +<pre> +// A channel that sends a notification on each visit. +// (Probably want the channel to be buffered.) +type Chan chan *http.Request + +func (ch Chan) ServeHTTP(w http.ResponseWriter, req *http.Request) { + ch <- req + fmt.Fprint(w, "notification sent") +} +</pre> +<p> +Finally, let's say we wanted to present on <code>/args</code> the arguments +used when invoking the server binary. +It's easy to write a function to print the arguments. +</p> +<pre> +func ArgServer() { + for i, s := range os.Args { + fmt.Println(s) + } +} +</pre> +<p> +How do we turn that into an HTTP server? We could make <code>ArgServer</code> +a method of some type whose value we ignore, but there's a cleaner way. +Since we can define a method for any type except pointers and interfaces, +we can write a method for a function. +The <code>http</code> package contains this code: +</p> +<pre> +// The HandlerFunc type is an adapter to allow the use of +// ordinary functions as HTTP handlers. If f is a function +// with the appropriate signature, HandlerFunc(f) is a +// Handler object that calls f. +type HandlerFunc func(ResponseWriter, *Request) + +// ServeHTTP calls f(c, req). +func (f HandlerFunc) ServeHTTP(w ResponseWriter, req *Request) { + f(w, req) +} +</pre> +<p> +<code>HandlerFunc</code> is a type with a method, <code>ServeHTTP</code>, +so values of that type can serve HTTP requests. Look at the implementation +of the method: the receiver is a function, <code>f</code>, and the method +calls <code>f</code>. That may seem odd but it's not that different from, say, +the receiver being a channel and the method sending on the channel. +</p> +<p> +To make <code>ArgServer</code> into an HTTP server, we first modify it +to have the right signature. +</p> +<pre> +// Argument server. +func ArgServer(w http.ResponseWriter, req *http.Request) { + for i, s := range os.Args { + fmt.Fprintln(w, s) + } +} +</pre> +<p> +<code>ArgServer</code> now has same signature as <code>HandlerFunc</code>, +so it can be converted to that type to access its methods, +just as we converted <code>Sequence</code> to <code>IntArray</code> +to access <code>IntArray.Sort</code>. +The code to set it up is concise: +</p> +<pre> +http.Handle("/args", http.HandlerFunc(ArgServer)) +</pre> +<p> +When someone visits the page <code>/args</code>, +the handler installed at that page has value <code>ArgServer</code> +and type <code>HandlerFunc</code>. +The HTTP server will invoke the method <code>ServeHTTP</code> +of that type, with <code>ArgServer</code> as the receiver, which will in turn call +<code>ArgServer</code> (via the invocation <code>f(c, req)</code> +inside <code>HandlerFunc.ServeHTTP</code>). +The arguments will then be displayed. +</p> +<p> +In this section we have made an HTTP server from a struct, an integer, +a channel, and a function, all because interfaces are just sets of +methods, which can be defined for (almost) any type. +</p> + +<h2 id="embedding">Embedding</h2> + +<p> +Go does not provide the typical, type-driven notion of subclassing, +but it does have the ability to “borrow” pieces of an +implementation by <em>embedding</em> types within a struct or +interface. +</p> +<p> +Interface embedding is very simple. +We've mentioned the <code>io.Reader</code> and <code>io.Writer</code> interfaces before; +here are their definitions. +</p> +<pre> +type Reader interface { + Read(p []byte) (n int, err os.Error) +} + +type Writer interface { + Write(p []byte) (n int, err os.Error) +} +</pre> +<p> +The <code>io</code> package also exports several other interfaces +that specify objects that can implement several such methods. +For instance, there is <code>io.ReadWriter</code>, an interface +containing both <code>Read</code> and <code>Write</code>. +We could specify <code>io.ReadWriter</code> by listing the +two methods explicitly, but it's easier and more evocative +to embed the two interfaces to form the new one, like this: +</p> +<pre> +// ReadWriter is the interface that combines the Reader and Writer interfaces. +type ReadWriter interface { + Reader + Writer +} +</pre> +<p> +This says just what it looks like: A <code>ReadWriter</code> can do +what a <code>Reader</code> does <em>and</em> what a <code>Writer</code> +does; it is a union of the embedded interfaces (which must be disjoint +sets of methods). +Only interfaces can be embedded within interfaces. +<p> +The same basic idea applies to structs, but with more far-reaching +implications. The <code>bufio</code> package has two struct types, +<code>bufio.Reader</code> and <code>bufio.Writer</code>, each of +which of course implements the analogous interfaces from package +<code>io</code>. +And <code>bufio</code> also implements a buffered reader/writer, +which it does by combining a reader and a writer into one struct +using embedding: it lists the types within the struct +but does not give them field names. +</p> +<pre> +// ReadWriter stores pointers to a Reader and a Writer. +// It implements io.ReadWriter. +type ReadWriter struct { + *Reader // *bufio.Reader + *Writer // *bufio.Writer +} +</pre> +<p> +The embedded elements are pointers to structs and of course +must be initialized to point to valid structs before they +can be used. +The <code>ReadWriter</code> struct could be written as +</p> +<pre> +type ReadWriter struct { + reader *Reader + writer *Writer +} +</pre> +<p> +but then to promote the methods of the fields and to +satisfy the <code>io</code> interfaces, we would also need +to provide forwarding methods, like this: +</p> +<pre> +func (rw *ReadWriter) Read(p []byte) (n int, err os.Error) { + return rw.reader.Read(p) +} +</pre> +<p> +By embedding the structs directly, we avoid this bookkeeping. +The methods of embedded types come along for free, which means that <code>bufio.ReadWriter</code> +not only has the methods of <code>bufio.Reader</code> and <code>bufio.Writer</code>, +it also satisfies all three interfaces: +<code>io.Reader</code>, +<code>io.Writer</code>, and +<code>io.ReadWriter</code>. +</p> +<p> +There's an important way in which embedding differs from subclassing. When we embed a type, +the methods of that type become methods of the outer type, +but when they are invoked the receiver of the method is the inner type, not the outer one. +In our example, when the <code>Read</code> method of a <code>bufio.ReadWriter</code> is +invoked, it has exactly the same effect as the forwarding method written out above; +the receiver is the <code>reader</code> field of the <code>ReadWriter</code>, not the +<code>ReadWriter</code> itself. +</p> +<p> +Embedding can also be a simple convenience. +This example shows an embedded field alongside a regular, named field. +</p> +<pre> +type Job struct { + Command string + *log.Logger +} +</pre> +<p> +The <code>Job</code> type now has the <code>Log</code>, <code>Logf</code> +and other +methods of <code>*log.Logger</code>. We could have given the <code>Logger</code> +a field name, of course, but it's not necessary to do so. And now, once +initialized, we can +log to the <code>Job</code>: +</p> +<pre> +job.Log("starting now...") +</pre> +<p> +The <code>Logger</code> is a regular field of the struct and we can initialize +it in the usual way with a constructor, +</p> +<pre> +func NewJob(command string, logger *log.Logger) *Job { + return &Job{command, logger} +} +</pre> +<p> +or with a composite literal, +</p> +<pre> +job := &Job{command, log.New(os.Stderr, "Job: ", log.Ldate)} +</pre> +<p> +If we need to refer to an embedded field directly, the type name of the field, +ignoring the package qualifier, serves as a field name. If we needed to access the +<code>*log.Logger</code> of a <code>Job</code> variable <code>job</code>, +we would write <code>job.Logger</code>. +This would be useful if we wanted to refine the methods of <code>Logger</code>. +</p> +<pre> +func (job *Job) Logf(format string, args ...interface{}) { + job.Logger.Logf("%q: %s", job.Command, fmt.Sprintf(format, args)) +} +</pre> +<p> +Embedding types introduces the problem of name conflicts but the rules to resolve +them are simple. +First, a field or method <code>X</code> hides any other item <code>X</code> in a more deeply +nested part of the type. +If <code>log.Logger</code> contained a field or method called <code>Command</code>, the <code>Command</code> field +of <code>Job</code> would dominate it. +</p> +<p> +Second, if the same name appears at the same nesting level, it is usually an error; +it would be erroneous to embed <code>log.Logger</code> if the <code>Job</code> struct +contained another field or method called <code>Logger</code>. +However, if the duplicate name is never mentioned in the program outside the type definition, it is OK. +This qualification provides some protection against changes made to types embedded from outside; there +is no problem if a field is added that conflicts with another field in another subtype if neither field +is ever used. +</p> + + +<h2 id="concurrency">Concurrency</h2> + +<h3 id="sharing">Share by communicating</h3> + +<p> +Concurrent programming is a large topic and there is space only for some +Go-specific highlights here. +</p> +<p> +Concurrent programming in many environments is made difficult by the +subtleties required to implement correct access to shared variables. Go encourages +a different approach in which shared values are passed around on channels +and, in fact, never actively shared by separate threads of execution. +Only one goroutine has access to the value at any given time. +Data races cannot occur, by design. +To encourage this way of thinking we have reduced it to a slogan: +</p> +<blockquote> +Do not communicate by sharing memory; +instead, share memory by communicating. +</blockquote> +<p> +This approach can be taken too far. Reference counts may be best done +by putting a mutex around an integer variable, for instance. But as a +high-level approach, using channels to control access makes it easier +to write clear, correct programs. +</p> +<p> +One way to think about this model is to consider a typical single-threaded +program running on one CPU. It has no need for synchronization primitives. +Now run another such instance; it too needs no synchronization. Now let those +two communicate; if the communication is the synchronizer, there's still no need +for other synchronization. Unix pipelines, for example, fit this model +perfectly. Although Go's approach to concurrency originates in Hoare's +Communicating Sequential Processes (CSP), +it can also be seen as a type-safe generalization of Unix pipes. +</p> + +<h3 id="goroutines">Goroutines</h3> + +<p> +They're called <em>goroutines</em> because the existing +terms—threads, coroutines, processes, and so on—convey +inaccurate connotations. A goroutine has a simple model: it is a +function executing in parallel with other goroutines in the same +address space. It is lightweight, costing little more than the +allocation of stack space. +And the stacks start small, so they are cheap, and grow +by allocating (and freeing) heap storage as required. +</p> +<p> +Goroutines are multiplexed onto multiple OS threads so if one should +block, such as while waiting for I/O, others continue to run. Their +design hides many of the complexities of thread creation and +management. +</p> +<p> +Prefix a function or method call with the <code>go</code> +keyword to run the call in a new goroutine. +When the call completes, the goroutine +exits, silently. (The effect is similar to the Unix shell's +<code>&</code> notation for running a command in the +background.) +</p> +<pre> +go list.Sort() // run list.Sort in parallel; don't wait for it. +</pre> +<p> +A function literal can be handy in a goroutine invocation. +<pre> +func Announce(message string, delay int64) { + go func() { + time.Sleep(delay) + fmt.Println(message) + }() // Note the parentheses - must call the function. +} +</pre> +<p> +In Go, function literals are closures: the implementation makes +sure the variables referred to by the function survive as long as they are active. +<p> +These examples aren't too practical because the functions have no way of signaling +completion. For that, we need channels. +</p> + +<h3 id="channels">Channels</h3> + +<p> +Like maps, channels are a reference type and are allocated with <code>make</code>. +If an optional integer parameter is provided, it sets the buffer size for the channel. +The default is zero, for an unbuffered or synchronous channel. +</p> +<pre> +ci := make(chan int) // unbuffered channel of integers +cj := make(chan int, 0) // unbuffered channel of integers +cs := make(chan *os.File, 100) // buffered channel of pointers to Files +</pre> +<p> +Channels combine communication—the exchange of a value—with +synchronization—guaranteeing that two calculations (goroutines) are in +a known state. +</p> +<p> +There are lots of nice idioms using channels. Here's one to get us started. +In the previous section we launched a sort in the background. A channel +can allow the launching goroutine to wait for the sort to complete. +</p> +<pre> +c := make(chan int) // Allocate a channel. +// Start the sort in a goroutine; when it completes, signal on the channel. +go func() { + list.Sort() + c <- 1 // Send a signal; value does not matter. +}() +doSomethingForAWhile() +<-c // Wait for sort to finish; discard sent value. +</pre> +<p> +Receivers always block until there is data to receive. +If the channel is unbuffered, the sender blocks until the receiver has +received the value. +If the channel has a buffer, the sender blocks only until the +value has been copied to the buffer; if the buffer is full, this +means waiting until some receiver has retrieved a value. +</p> +<p> +A buffered channel can be used like a semaphore, for instance to +limit throughput. In this example, incoming requests are passed +to <code>handle</code>, which sends a value into the channel, processes +the request, and then receives a value from the channel. +The capacity of the channel buffer limits the number of +simultaneous calls to <code>process</code>. +</p> +<pre> +var sem = make(chan int, MaxOutstanding) + +func handle(r *Request) { + sem <- 1 // Wait for active queue to drain. + process(r) // May take a long time. + <-sem // Done; enable next request to run. +} + +func Serve(queue chan *Request) { + for { + req := <-queue + go handle(req) // Don't wait for handle to finish. + } +} +</pre> +<p> +Here's the same idea implemented by starting a fixed +number of <code>handle</code> goroutines all reading from the request +channel. +The number of goroutines limits the number of simultaneous +calls to <code>process</code>. +This <code>Serve</code> function also accepts a channel on which +it will be told to exit; after launching the goroutines it blocks +receiving from that channel. +</p> +<pre> +func handle(queue chan *Request) { + for r := range queue { + process(r) + } +} + +func Serve(clientRequests chan *clientRequests, quit chan bool) { + // Start handlers + for i := 0; i < MaxOutstanding; i++ { + go handle(clientRequests) + } + <-quit // Wait to be told to exit. +} +</pre> + +<h3 id="chan_of_chan">Channels of channels</h3> +<p> +One of the most important properties of Go is that +a channel is a first-class value that can be allocated and passed +around like any other. A common use of this property is +to implement safe, parallel demultiplexing. +<p> +In the example in the previous section, <code>handle</code> was +an idealized handler for a request but we didn't define the +type it was handling. If that type includes a channel on which +to reply, each client can provide its own path for the answer. +Here's a schematic definition of type <code>Request</code>. +</p> +<pre> +type Request struct { + args []int + f func([]int) int + resultChan chan int +} +</pre> +<p> +The client provides a function and its arguments, as well as +a channel inside the request object on which to receive the answer. +</p> +<pre> +func sum(a []int) (s int) { + for _, v := range a { + s += v + } + return +} + +request := &Request{[]int{3, 4, 5}, sum, make(chan int)} +// Send request +clientRequests <- request +// Wait for response. +fmt.Printf("answer: %d\n", <-request.resultChan) +</pre> +<p> +On the server side, the handler function is the only thing that changes. +</p> +<pre> +func handle(queue chan *Request) { + for req := range queue { + req.resultChan <- req.f(req.args) + } +} +</pre> +<p> +There's clearly a lot more to do to make it realistic, but this +code is a framework for a rate-limited, parallel, non-blocking RPC +system, and there's not a mutex in sight. +</p> + +<h3 id="parallel">Parallelization</h3> +<p> +Another application of these ideas is to parallelize a calculation +across multiple CPU cores. If the calculation can be broken into +separate pieces, it can be parallelized, with a channel to signal +when each piece completes. +</p> +<p> +Let's say we have an expensive operation to perform on a vector of items, +and that the value of the operation on each item is independent, +as in this idealized example. +</p> +<pre> +type Vector []float64 + +// Apply the operation to v[i], v[i+1] ... up to v[n-1]. +func (v Vector) DoSome(i, n int, u Vector, c chan int) { + for ; i < n; i++ { + v[i] += u.Op(v[i]) + } + c <- 1 // signal that this piece is done +} +</pre> +<p> +We launch the pieces independently in a loop, one per CPU. +They can complete in any order but it doesn't matter; we just +count the completion signals by draining the channel after +launching all the goroutines. +</p> +<pre> +const NCPU = 4 // number of CPU cores + +func (v Vector) DoAll(u Vector) { + c := make(chan int, NCPU) // Buffering optional but sensible. + for i := 0; i < NCPU; i++ { + go v.DoSome(i*len(v)/NCPU, (i+1)*len(v)/NCPU, u, c) + } + // Drain the channel. + for i := 0; i < NCPU; i++ { + <-c // wait for one task to complete + } + // All done. +} + +</pre> + +<p> +The current implementation of <code>gc</code> (<code>6g</code>, etc.) +will not parallelize this code by default. +It dedicates only a single core to user-level processing. An +arbitrary number of goroutines can be blocked in system calls, but +by default only one can be executing user-level code at any time. +It should be smarter and one day it will be smarter, but until it +is if you want CPU parallelism you must tell the run-time +how many goroutines you want executing code simultaneously. There +are two related ways to do this. Either run your job with environment +variable <code>GOMAXPROCS</code> set to the number of cores to use +(default 1); or import the <code>runtime</code> package and call +<code>runtime.GOMAXPROCS(NCPU)</code>. +Again, this requirement is expected to be retired as the scheduling and run-time improve. +</p> + +<h3 id="leaky_buffer">A leaky buffer</h3> + +<p> +The tools of concurrent programming can even make non-concurrent +ideas easier to express. Here's an example abstracted from an RPC +package. The client goroutine loops receiving data from some source, +perhaps a network. To avoid allocating and freeing buffers, it keeps +a free list, and uses a buffered channel to represent it. If the +channel is empty, a new buffer gets allocated. +Once the message buffer is ready, it's sent to the server on +<code>serverChan</code>. +</p> +<pre> +var freeList = make(chan *Buffer, 100) +var serverChan = make(chan *Buffer) + +func client() { + for { + var b *Buffer + // Grab a buffer if available; allocate if not. + select { + case b = <-freeList: + // Got one; nothing more to do. + default: + // None free, so allocate a new one. + b = new(Buffer) + } + load(b) // Read next message from the net. + serverChan <- b // Send to server. + } +} +</pre> +<p> +The server loop receives each message from the client, processes it, +and returns the buffer to the free list. +</p> +<pre> +func server() { + for { + b := <-serverChan // Wait for work. + process(b) + // Reuse buffer if there's room. + select { + case freeList <- b: + // Buffer on free list; nothing more to do. + default: + // Free list full, just carry on. + } + } +} +</pre> +<p> +The client attempts to retrieve a buffer from <code>freeList</code>; +if none is available, it allocates a fresh one. +The server's send to <code>freeList</code> puts <code>b</code> back +on the free list unless the list is full, in which case the +buffer is dropped on the floor to be reclaimed by +the garbage collector. +(The <code>default</code> clauses in the <code>select</code> +statements execute when no other case is ready, +meaning that the <code>selects</code> never block.) +This implementation builds a leaky bucket free list +in just a few lines, relying on the buffered channel and +the garbage collector for bookkeeping. +</p> + +<h2 id="errors">Errors</h2> + +<p> +Library routines must often return some sort of error indication to +the caller. As mentioned earlier, Go's multivalue return makes it +easy to return a detailed error description alongside the normal +return value. By convention, errors have type <code>os.Error</code>, +a simple interface. +</p> +<pre> +type Error interface { + String() string +} +</pre> +<p> +A library writer is free to implement this interface with a +richer model under the covers, making it possible not only +to see the error but also to provide some context. +For example, <code>os.Open</code> returns an <code>os.PathError</code>. +</p> +<pre> +// PathError records an error and the operation and +// file path that caused it. +type PathError struct { + Op string // "open", "unlink", etc. + Path string // The associated file. + Error Error // Returned by the system call. +} + +func (e *PathError) String() string { + return e.Op + " " + e.Path + ": " + e.Error.String() +} +</pre> +<p> +<code>PathError</code>'s <code>String</code> generates +a string like this: +</p> +<pre> +open /etc/passwx: no such file or directory +</pre> +<p> +Such an error, which includes the problematic file name, the +operation, and the operating system error it triggered, is useful even +if printed far from the call that caused it; +it is much more informative than the plain +"no such file or directory". +</p> + +<p> +When feasible, error strings should identify their origin, such as by having +a prefix naming the package that generated the error. For example, in package +image, the string representation for a decoding error due to an unknown format +is "image: unknown format". +</p> + +<p> +Callers that care about the precise error details can +use a type switch or a type assertion to look for specific +errors and extract details. For <code>PathErrors</code> +this might include examining the internal <code>Error</code> +field for recoverable failures. +</p> + +<pre> +for try := 0; try < 2; try++ { + file, err = os.Open(filename) + if err == nil { + return + } + if e, ok := err.(*os.PathError); ok && e.Error == os.ENOSPC { + deleteTempFiles() // Recover some space. + continue + } + return +} +</pre> + +<h3 id="panic">Panic</h3> + +<p> +The usual way to report an error to a caller is to return an +<code>os.Error</code> as an extra return value. The canonical +<code>Read</code> method is a well-known instance; it returns a byte +count and an <code>os.Error</code>. But what if the error is +unrecoverable? Sometimes the program simply cannot continue. +</p> + +<p> +For this purpose, there is a built-in function <code>panic</code> +that in effect creates a run-time error that will stop the program +(but see the next section). The function takes a single argument +of arbitrary type—often a string—to be printed as the +program dies. It's also a way to indicate that something impossible has +happened, such as exiting an infinite loop. In fact, the compiler +recognizes a <code>panic</code> at the end of a function and +suppresses the usual check for a <code>return</code> statement. +</p> + + +<pre> +// A toy implementation of cube root using Newton's method. +func CubeRoot(x float64) float64 { + z := x/3 // Arbitrary initial value + for i := 0; i < 1e6; i++ { + prevz := z + z -= (z*z*z-x) / (3*z*z) + if veryClose(z, prevz) { + return z + } + } + // A million iterations has not converged; something is wrong. + panic(fmt.Sprintf("CubeRoot(%g) did not converge", x)) +} +</pre> + +<p> +This is only an example but real library functions should +avoid <code>panic</code>. If the problem can be masked or worked +around, it's always better to let things continue to run rather +than taking down the whole program. One possible counterexample +is during initialization: if the library truly cannot set itself up, +it might be reasonable to panic, so to speak. +</p> + +<pre> +var user = os.Getenv("USER") + +func init() { + if user == "" { + panic("no value for $USER") + } +} +</pre> + +<h3 id="recover">Recover</h3> + +<p> +When <code>panic</code> is called, including implicitly for run-time +errors such as indexing an array out of bounds or failing a type +assertion, it immediately stops execution of the current function +and begins unwinding the stack of the goroutine, running any deferred +functions along the way. If that unwinding reaches the top of the +goroutine's stack, the program dies. However, it is possible to +use the built-in function <code>recover</code> to regain control +of the goroutine and resume normal execution. +</p> + +<p> +A call to <code>recover</code> stops the unwinding and returns the +argument passed to <code>panic</code>. Because the only code that +runs while unwinding is inside deferred functions, <code>recover</code> +is only useful inside deferred functions. +</p> + +<p> +One application of <code>recover</code> is to shut down a failing goroutine +inside a server without killing the other executing goroutines. +</p> + +<pre> +func server(workChan <-chan *Work) { + for work := range workChan { + go safelyDo(work) + } +} + +func safelyDo(work *Work) { + defer func() { + if err := recover(); err != nil { + log.Println("work failed:", err) + } + }() + do(work) +} +</pre> + +<p> +In this example, if <code>do(work)</code> panics, the result will be +logged and the goroutine will exit cleanly without disturbing the +others. There's no need to do anything else in the deferred closure; +calling <code>recover</code> handles the condition completely. +</p> + +<p> +Because <code>recover</code> always returns <code>nil</code> unless called directly +from a deferred function, deferred code can call library routines that themselves +use <code>panic</code> and <code>recover</code> without failing. As an example, +the deferred function in <code>safelyDo</code> might call a logging function before +calling <code>recover</code>, and that logging code would run unaffected +by the panicking state. +</p> + +<p> +With our recovery pattern in place, the <code>do</code> +function (and anything it calls) can get out of any bad situation +cleanly by calling <code>panic</code>. We can use that idea to +simplify error handling in complex software. Let's look at an +idealized excerpt from the <code>regexp</code> package, which reports +parsing errors by calling <code>panic</code> with a local +<code>Error</code> type. Here's the definition of <code>Error</code>, +an <code>error</code> method, and the <code>Compile</code> function. +</p> + +<pre> +// Error is the type of a parse error; it satisfies os.Error. +type Error string +func (e Error) String() string { + return string(e) +} + +// error is a method of *Regexp that reports parsing errors by +// panicking with an Error. +func (regexp *Regexp) error(err string) { + panic(Error(err)) +} + +// Compile returns a parsed representation of the regular expression. +func Compile(str string) (regexp *Regexp, err os.Error) { + regexp = new(Regexp) + // doParse will panic if there is a parse error. + defer func() { + if e := recover(); e != nil { + regexp = nil // Clear return value. + err = e.(Error) // Will re-panic if not a parse error. + } + }() + return regexp.doParse(str), nil +} +</pre> + +<p> +If <code>doParse</code> panics, the recovery block will set the +return value to <code>nil</code>—deferred functions can modify +named return values. It then will then check, in the assignment +to <code>err</code>, that the problem was a parse error by asserting +that it has type <code>Error</code>. +If it does not, the type assertion will fail, causing a run-time error +that continues the stack unwinding as though nothing had interrupted +it. This check means that if something unexpected happens, such +as an array index out of bounds, the code will fail even though we +are using <code>panic</code> and <code>recover</code> to handle +user-triggered errors. +</p> + +<p> +With error handling in place, the <code>error</code> method +makes it easy to report parse errors without worrying about unwinding +the parse stack by hand. +</p> + +<p> +Useful though this pattern is, it should be used only within a package. +<code>Parse</code> turns its internal <code>panic</code> calls into +<code>os.Error</code> values; it does not expose <code>panics</code> +to its client. That is a good rule to follow. +</p> + +<p> +By the way, this re-panic idiom changes the panic value if an actual +error occurs. However, both the original and new failures will be +presented in the crash report, so the root cause of the problem will +still be visible. Thus this simple re-panic approach is usually +sufficient—it's a crash after all—but if you want to +display only the original value, you can write a little more code to +filter unexpected problems and re-panic with the original error. +That's left as an exercise for the reader. +</p> + + +<h2 id="web_server">A web server</h2> + +<p> +Let's finish with a complete Go program, a web server. +This one is actually a kind of web re-server. +Google provides a service at +<a href="http://chart.apis.google.com">http://chart.apis.google.com</a> +that does automatic formatting of data into charts and graphs. +It's hard to use interactively, though, +because you need to put the data into the URL as a query. +The program here provides a nicer interface to one form of data: given a short piece of text, +it calls on the chart server to produce a QR code, a matrix of boxes that encode the +text. +That image can be grabbed with your cell phone's camera and interpreted as, +for instance, a URL, saving you typing the URL into the phone's tiny keyboard. +</p> +<p> +Here's the complete program. +An explanation follows. +</p> + +<pre> +package main + +import ( + "flag" + "http" + "io" + "log" + "old/template" // New template package coming soon... +) + +var addr = flag.String("addr", ":1718", "http service address") // Q=17, R=18 +var fmap = template.FormatterMap{ + "html": template.HTMLFormatter, + "url+html": UrlHtmlFormatter, +} +var templ = template.MustParse(templateStr, fmap) + +func main() { + flag.Parse() + http.Handle("/", http.HandlerFunc(QR)) + err := http.ListenAndServe(*addr, nil) + if err != nil { + log.Fatal("ListenAndServe:", err) + } +} + +func QR(w http.ResponseWriter, req *http.Request) { + templ.Execute(w, req.FormValue("s")) +} + +func UrlHtmlFormatter(w io.Writer, fmt string, v ...interface{}) { + template.HTMLEscape(w, []byte(http.URLEscape(v[0].(string)))) +} + + +const templateStr = ` +<html> +<head> +<title>QR Link Generator</title> +</head> +<body> +{.section @} +<img src="http://chart.apis.google.com/chart?chs=300x300&cht=qr&choe=UTF-8&chl={@|url+html}" +/> +<br> +{@|html} +<br> +<br> +{.end} +<form action="/" name=f method="GET"><input maxLength=1024 size=70 +name=s value="" title="Text to QR Encode"><input type=submit +value="Show QR" name=qr> +</form> +</body> +</html> +` +</pre> + +<p> +The pieces up to <code>main</code> should be easy to follow. +The one flag sets a default HTTP port for our server. The template +variable <code>templ</code> is where the fun happens. It builds an HTML template +that will be executed by the server to display the page; more about +that in a moment. +</p> +<p> +The <code>main</code> function parses the flags and, using the mechanism +we talked about above, binds the function <code>QR</code> to the root path +for the server. Then <code>http.ListenAndServe</code> is called to start the +server; it blocks while the server runs. +</p> +<p> +<code>QR</code> just receives the request, which contains form data, and +executes the template on the data in the form value named <code>s</code>. +</p> +<p> +The template package, inspired by <a +href="http://code.google.com/p/json-template">json-template</a>, is +powerful; +this program just touches on its capabilities. +In essence, it rewrites a piece of text on the fly by substituting elements derived +from data items passed to <code>templ.Execute</code>, in this case the +form value. +Within the template text (<code>templateStr</code>), +brace-delimited pieces denote template actions. +The piece from the <code>{.section @}</code> +to <code>{.end}</code> executes with the value of the data item <code>@</code>, +which is a shorthand for “the current item”, which is the form value. +(When the string is empty, this piece of the template is suppressed.) +</p> +<p> +The snippet <code>{@|url+html}</code> says to run the data through the formatter +installed in the formatter map (<code>fmap</code>) +under the name <code>"url+html"</code>. +That is the function <code>UrlHtmlFormatter</code>, which sanitizes the string +for safe display on the web page. +</p> +<p> +The rest of the template string is just the HTML to show when the page loads. +If this is too quick an explanation, see the <a href="/pkg/template/">documentation</a> +for the template package for a more thorough discussion. +</p> +<p> +And there you have it: a useful webserver in a few lines of code plus some +data-driven HTML text. +Go is powerful enough to make a lot happen in a few lines. +</p> + +<!-- +TODO +<pre> +verifying implementation +type Color uint32 + +// Check that Color implements image.Color and image.Image +var _ image.Color = Black +var _ image.Image = Black +</pre> +--> + diff --git a/doc/frontpage.css b/doc/frontpage.css new file mode 100644 index 000000000..299855ce9 --- /dev/null +++ b/doc/frontpage.css @@ -0,0 +1,143 @@ +/* Overloads to all.css */ +#container { width: 76em } +.left-column { width: 48%; } +.right-column { width: 48%; } + +/* Frontpage styles */ +#content-introductory code { + font-family: "Bitstream Vera Sans Mono", "Andale Mono", monospace; +} +#content-introductory input, select, textarea { + font-family: "Bitstream Vera Sans", Verdana, sans-serif; + font-size: 1em; +} +span.keyword { + font-family: Cambria, Georgia, Times, "Times New Roman", serif; + font-size: 1.15em; + font-style: italic; +} +#content h3, #content h2 { + margin: 0; + font-size: 1em; + background: none; + border: none; + padding: 0; +} +#content .more { + color: #999; + font-weight: normal; +} +#frontpage h2#branding-tagline { + font-weight: normal; + font-style: italic; +} +#resources { + position: relative; + margin-top: 1em; +} +#resources h3 { + margin-top: 0; + margin-bottom: -.5em; + font-size: 1em; + font-weight: normal; +} +#resources-users { + float: left; + width: 48%; +} +#resources-contributors { + float: right; + width: 50%; +} +#resources ul { + padding-left: 2em; +} +#resources li { + margin-bottom: 0.5em; +} +#content-rotating { + height: 200px; +} +#content-videos { + float: left; + width: 170px; +} +#content-videos .thumbnail { + width: 150px; + height: 103px; + background-repeat: no-repeat; + border: none; +} +#content-videos .thumbnail._001 { + background: url(/doc/video-001.png); +} +#content-videos .thumbnail._002 { + background: url(/doc/video-002.png); +} +#content-videos .thumbnail._003 { + background: url(/doc/video-003.png); +} +#content-videos .thumbnail._004 { + background: url(/doc/video-004.png); +} +#content-videos .thumbnail._005 { + background: url(/doc/video-005.jpg); +} +#content-videos a.video { + display: inline-block; + width: 150px; + margin-right: .30em; + margin-top: 1.2em; +} +#content-videos a.video .caption { + display: block; + text-align: center; +} +#content-videos a.video .caption.title { + margin-top: .31em; + font-weight: bold; +} +#content-blog ul { + margin-top: 1em; + margin-left: 0; + padding-left: 0; +} +#content-blog li { + list-style: none; + margin-bottom: 1em; +} +#content-blog li a { + color: #999; + text-decoration: none; +} +#content-blog .date { + color: #999; + font-size: 0.8em; + display: inline-block; + margin-left: 0.5em; +} +#content-blog li a:link .title { + color: #04a; +} +#content-blog li a:visited .title { + color: #04a; +} +#content-blog li a:hover .title { + color: #a40; + text-decoration: underline; +} +#content-blog li a:active .title { + color: #c00; +} +.navtop { + display: none !important; +} +.how { + float: right; + font-size: 75%; +} +.unsupported { + font-weight: bold; + color: red; +} + diff --git a/doc/gccgo_contribute.html b/doc/gccgo_contribute.html new file mode 100644 index 000000000..8eeb3a5c5 --- /dev/null +++ b/doc/gccgo_contribute.html @@ -0,0 +1,99 @@ +<!-- Contributing to the gccgo frontend --> + +<h2>Introduction</h2> + +<p> +These are some notes on contributing to the <code>gccgo</code> +frontend for GCC. For information on contributing to parts of Go other +than <code>gccgo</code>, see <a href="contribute.html">Contributing to +the Go project</a>. For information on building <code>gccgo</code> +for yourself, see <a href="gccgo_install.html">Setting up and using +gccgo</a>. +</p> + +<h2>Legal Prerequisites</h2> + +<p> +You must follow the <a href="contribute.html#copyright">Go copyright +rules.</a> +</p> + +<h2>Code</h2> + +<p> +The source code for the <code>gccgo</code> frontend may be found at +<a href="http://code.google.com/p/gofrontend">http://code.google.com/p/gofrontend</a>. +Changes made to that project are routinely merged into the source code +hosted at <code>gcc.gnu.org</code>. The <code>gofrontend</code> +project includes only the Go frontend proper. These are the files +which in the <code>gcc</code> sources may be found in the +directories <code>gcc/go</code> and <code>libgo</code>. +The <code>gcc</code> sources also include a copy of +the <code>test</code> directory +from <a href="http://code.google.com/p/go">the main Go repository</a>. + +<p> +The frontend is written in C++ and as such the GNU coding standards do +not entirely apply; in writing code for the frontend, follow the +formatting of the surrounding code. Although the frontend is +currently closely tied to the rest of the <code>gcc</code> codebase, +we plan to make it more independent. Any new code that uses other +parts of <code>gcc</code> should be placed in an appropriate file, +such as <code>gogo-tree.cc</code>. Eventually +all <code>gcc</code>-specific code should migrate to +a <code>gcc-interface</code> subdirectory. +</p> + +<p> +The run-time library for <code>gccgo</code> is mostly the same as the +library in <a href="http://code.google.com/p/go">the main Go +repository</a>. The library code in the Go repository is periodically +copied into the <code>gofrontend</code> and the <code>gcc</code> +repositories. Accordingly, most library changes should be made in the +main Go repository. Changes to the few <code>gccgo</code>-specific +parts of the library should follow the process described here. +The <code>gccgo</code>-specific parts of the library are everything in +the <code>libgo</code> directory except for the <code>libgo/go</code> +subdirectory. +</p> + +<h2>Testing</h2> + +<p> +All patches must be tested. There are two test suites. A patch that +introduces new failures is not acceptable. +</p> + +<p> +To run the compiler test suite, run <code>make check-go</code> in the +<code>gcc</code> subdirectory of your build directory. This will run +various tests underneath <code>gcc/testsuite/go.*</code>. This +includes a copy of the tests in the main Go repository, which are run +using the DejaGNU script found in +in <code>gcc/testsuite/go.test/go-test.exp</code>. Many of the +compiler tests may be run without the Go library, but some do require +the library to built first. +</p> + +<p> +To run the library test suite, run <code>make +check-target-libgo</code> in the top level of your build directory. +</p> + +<p> +Most new tests should be submitted to the main Go repository for +copying into the <code>gccgo</code> repository. If there is a need +for specific tests for <code>gccgo</code>, they should go in +the <code>gcc/testsuite/go.go-torture</code> +or <code>gcc/testsuite/go.dg</code> directories in +the <code>gcc.gnu.org</code> repository. +</p> + +<h2>Submitting Changes</h2> + +<p> +Changes to the Go frontend should follow the same process as for the +main Go repository, only for the <code>gofrontend</code> project +rather than the <code>go</code> project. Those changes will then be +merged into the <code>gcc</code> sources. +</p> diff --git a/doc/gccgo_install.html b/doc/gccgo_install.html new file mode 100644 index 000000000..159fab7bb --- /dev/null +++ b/doc/gccgo_install.html @@ -0,0 +1,409 @@ +<!-- Setting up and using gccgo --> + +<p> +This document explains how to use <code>gccgo</code>, a compiler for +the Go language. The <code>gccgo</code> compiler is a new frontend +for <code>gcc</code>, the widely used GNU compiler. Although the +frontend itself is under a BSD-style license, <code>gccgo</code> is +normally used as part of <code>gcc</code> and is then covered by +the <a href="http://www.gnu.org/licenses/gpl.html">GNU General Public +License</a>. +</p> + +<p> +Note that <code>gccgo</code> is not the <code>6g</code> compiler; see +the <a href="install.html">Installing Go</a> instructions for that +compiler. +</p> + +<h2 id="Source_code">Source code</h2> + +<p> +The <code>gccgo</code> source code is accessible via Subversion. The +<code>gcc</code> web site +has <a href="http://gcc.gnu.org/svn.html">instructions for getting the +<code>gcc</code> source code</a>. The <code>gccgo</code> source code +is a branch of the main <code>gcc</code> code +repository: <code>svn://gcc.gnu.org/svn/gcc/branches/gccgo</code>. +</p> + +<p> +Note that although <code>gcc.gnu.org</code> is the most convenient way +to get the source code for the compiler, that is not where the master +sources live. If you want to contribute changes to the gccgo +compiler, see <a href="gccgo_contribute.html">Contributing to +gccgo</a>. +</p> + + +<h2 id="Building">Building</h2> + +<p> +Building <code>gccgo</code> is just like building <code>gcc</code> +with one or two additional options. See +the <a href="http://gcc.gnu.org/install/">instructions on the gcc web +site</a>. When you run <code>configure</code>, add the +option <code>--enable-languages=c,c++,go</code> (along with other +languages you may want to build). If you are targeting a 32-bit x86, +then you will want to build <code>gccgo</code> to default to +supporting locked compare and exchange instructions; do this by also +using the <code>configure</code> option <code>--with-arch=i586</code> +(or a newer architecture, depending on where you need your programs to +run). +</p> + +<p> +On x86 GNU/Linux systems the <code>gccgo</code> compiler is able to +use a small discontiguous stack for goroutines. This permits programs +to run many more goroutines, since each goroutine can use a relatively +small stack. Doing this requires using a development version of +the <code>gold</code> linker. The easiest way to do this is to build +the GNU binutils, using <code>--enable-gold</code> when you run +the <code>configure</code> script, and to +use <code>--with-ld=GOLD_BINARY</code> when you +configure <code>gccgo</code>. A typical sequence would look like +this (you can replace <code>/opt/gold</code> with any directory to +which you have write access): +</p> + +<pre> +cvs -z 9 -d :pserver:anoncvs@sourceware.org:/cvs/src login +[password is "anoncvs"] +cvs -z 9 -d :pserver:anoncvs@sourceware.org:/cvs/src co binutils +mkdir binutils-objdir +cd binutils-objdir +../src/configure --enable-gold --prefix=/opt/gold +make +make install +</pre> + +<p> +A number of prerequisites are required to build <code>gcc</code>, as +described on the <a href="http://gcc.gnu.org/">gcc web site</a>. If +those are all available, then a typical build and install sequence +would look like this (only use the <code>--with-ld</code> option if +you built and installed the gold linker as described above): +</p> + +<pre> +svn checkout svn://gcc.gnu.org/svn/gcc/branches/gccgo gccgo +mkdir objdir +cd objdir +../gccgo/configure --enable-languages=c,c++,go --with-ld=/opt/gold/bin/ld +make +make install +</pre> + +<h2 id="Using_gccgo">Using gccgo</h2> + +<p> +The <code>gccgo</code> compiler works like other gcc frontends. + +<p> +To compile a file: + +<pre> +gccgo -c file.go +</pre> + +<p> +That produces <code>file.o</code>. To link files together to form an +executable: + +<pre> +gccgo -o file file.o +</pre> + +<p> +To run the resulting file, you will need to tell the program where to +find the compiled Go packages. This can be done either by setting +<code>LD_LIBRARY_PATH</code> in your environment: + +<pre> +LD_LIBRARY_PATH=/usr/lib/gcc/MACHINE/VERSION +</pre> + +<p> +or by passing a <code>-Wl,-R</code> option when you link: + +<pre> +gccgo -o file file.o -Wl,-R,/usr/lib/gcc/MACHINE/VERSION +</pre> + +<p> +or you can use the <code>-static-libgo</code> link-time option to link +statically against libgo, or you can do a fully static link (static +linking is the default for the <code>6l</code> Go linker). On most +systems, a static link will look something like: + +<pre> +gccgo -o file file.o -static -L /usr/lib/nptl -lgobegin -lgo -lpthread +</pre> + +<p> +You may get a warning about not creating an <code>.eh_frame_hdr</code> +section; this has nothing to do with Go, and may be ignored. In the +future the requirement of explicitly specifying +<code>-L /usr/lib/nptl -lgobegin -lgo -lpthread</code> +may be removed. + + +<h2 id="Options">Options</h2> + +<p> +The <code>gccgo</code> compiler supports all <code>gcc</code> options +that are language independent, notably the <code>-O</code> +and <code>-g</code> options. + +<p> +The <code>-fgo-prefix=PREFIX</code> option may be used to set a unique +prefix for the package being compiled. This option is intended for +use with large programs that contain many packages, in order to allow +multiple packages to use the same identifier as the package name. +The <code>PREFIX</code> may be any string; a good choice for the +string is the directory where the package will be installed. + +<p> +The <code>-fno-require-return-statement</code> option may be used to +disable the compiler error about functions missing return statements. +Note that there is no way to disable this error in <code>6g</code>. + +<p> +The <code>-I</code> and <code>-L</code> options, which are synonyms +for the compiler, may be used to set the search path for finding +imports. + + +<h2 id="Imports">Imports</h2> + +<p> +When you compile a file which exports something, the export +information will be stored directly in the object file. When +you import a package, you must tell <code>gccgo</code> how to +find the file. + +<p> +When you import the package <var>FILE</var> with <code>gccgo</code>, +it will look for the import data in the following files, and use the +first one that it finds. + +<ul> +<li><code><var>FILE</var>.gox</code> +<li><code><var>FILE</var>.o</code> +<li><code>lib<var>FILE</var>.so</code> +<li><code>lib<var>FILE</var>.a</code> +</ul> + +<p> +<code><var>FILE</var>.gox</code>, when used, will typically contain +nothing but export data. This can be generated from +<code><var>FILE</var>.o</code> via + +<pre> +objcopy -j .go_export FILE.o FILE.gox +</pre> + +<p> +The <code>gccgo</code> compiler will look in the current +directory for import files. In more complex scenarios you +may pass the <code>-I</code> or <code>-L</code> option to +<code>gccgo</code>. Both options take directories to search. The +<code>-L</code> option is also passed to the linker. + +The <code>gccgo</code> compiler does not currently (2009-11-06) record +the file name of imported packages in the object file. You must +arrange for the imported data to be linked into the program. + +<pre> +gccgo -c mypackage.go # Exports mypackage +gccgo -c main.go # Imports mypackage +gccgo -o main main.o mypackage.o # Explicitly links with mypackage.o +</pre> + +<h2 id="Unimplemented">Unimplemented</h2> + +<p> +Some Go features are not yet implemented in <code>gccgo</code>. As of +2010-08-23, the following are not implemented: + +<ul> +<li>goroutines are implemented as NPTL threads. If you can not use + the gold linker as described above, they are created with a fixed + stack size, and the number of goroutines that may be created at + one time is limited. +</ul> + +<h2 id="Debugging">Debugging</h2> + +<p> +If you use the <code>-g</code> option when you compile, you can run +<code>gdb</code> on your executable. The debugger doesn't (yet) +know anything about Go. However, you can set breakpoints, single-step, +etc. You can print variables, but they will be printed as though they +had C/C++ types. For numeric types this doesn't matter. Go strings +will show up as pointers to structures; to see the value +<code>print *stringvar</code>. In general Go strings, maps, channels +and interfaces are always represented as C pointers. + +<h2 id="C_Interoperability">C Interoperability</h2> + +<p> +When using <code>gccgo</code> there is limited interoperability with C, +or with C++ code compiled using <code>extern "C"</code>. + +<h3 id="Types">Types</h3> + +<p> +Basic types map directly: an <code>int</code> in Go is an <code>int</code> +in C, etc. Go <code>byte</code> is equivalent to C <code>unsigned char</code>. +Pointers in Go are pointers in C. A Go <code>struct</code> is the same as C +<code>struct</code> with the same fields and types. + +<p> +The Go <code>string</code> type is currently defined as a two-element +structure (this is <b style="color: red;">subject to change</b>): + +<pre> +struct __go_string { + const unsigned char *__data; + int __length; +}; +</pre> + +<p> +You can't pass arrays between C and Go. However, a pointer to an +array in Go is equivalent to a C pointer to the +equivalent of the element type. +For example, Go <code>*[10]int</code> is equivalent to C <code>int*</code>, +assuming that the C pointer does point to 10 elements. + +<p> +A slice in Go is a structure. The current definition is +(this is <b style="color: red;">subject to change</b>): + +<pre> +struct __go_slice { + void *__values; + int __count; + int __capacity; +}; +</pre> + +<p> +The type of a Go function with no receiver is equivalent to a C function +whose parameter types are equivalent. When a Go function returns more +than one value, the C function returns a struct. For example, these +functions have equivalent types: + +<pre> +func GoFunction(int) (int, float64) +struct { int i; float64 f; } CFunction(int) +</pre> + +<p> +A pointer to a Go function is equivalent to a pointer to a C function +when the functions have equivalent types. + +<p> +Go <code>interface</code>, <code>channel</code>, and <code>map</code> +types have no corresponding C type (<code>interface</code> is a +two-element struct and <code>channel</code> and <code>map</code> are +pointers to structs in C, but the structs are deliberately undocumented). C +<code>enum</code> types correspond to some integer type, but precisely +which one is difficult to predict in general; use a cast. C <code>union</code> +types have no corresponding Go type. C <code>struct</code> types containing +bitfields have no corresponding Go type. C++ <code>class</code> types have +no corresponding Go type. + +<p> +Memory allocation is completely different between C and Go, as Go uses +garbage collection. The exact guidelines in this area are undetermined, +but it is likely that it will be permitted to pass a pointer to allocated +memory from C to Go. The responsibility of eventually freeing the pointer +will remain with C side, and of course if the C side frees the pointer +while the Go side still has a copy the program will fail. When passing a +pointer from Go to C, the Go function must retain a visible copy of it in +some Go variable. Otherwise the Go garbage collector may delete the +pointer while the C function is still using it. + +<h3 id="Function_names">Function names</h3> + +<p> +Go code can call C functions directly using a Go extension implemented +in <code>gccgo</code>: a function declaration may be followed by +<code>__asm__("NAME")</code>. For example, here is how the C function +<code>open</code> can be declared in Go: + +<pre> +func c_open(name *byte, mode int, perm int) int __asm__ ("open"); +</pre> + +<p> +The C function naturally expects a nul terminated string, which in +Go is equivalent to a pointer to an array (not a slice!) of +<code>byte</code> with a terminating zero byte. So a sample call +from Go would look like (after importing the <code>os</code> package): + +<pre> +var name = [4]byte{'f', 'o', 'o', 0}; +i := c_open(&name[0], os.O_RDONLY, 0); +</pre> + +<p> +(this serves as an example only, to open a file in Go please use Go's +<code>os.Open</code> function instead). + +<p> +The name of Go functions accessed from C is subject to change. At present +the name of a Go function that does not have a receiver is +<code>prefix.package.Functionname</code>. The prefix is set by +the <code>-fgo-prefix</code> option used when the package is compiled; +if the option is not used, the default is simply <code>go</code>. +To call the function from C you must set the name using +a <code>gcc</code> extension similar to the <code>gccgo</code> +extension. + +<pre> +extern int go_function(int) __asm__ ("myprefix.mypackage.Function"); +</pre> + +<h3 id="Automatic_generation_of_Go_declarations_from_C_source_code"> +Automatic generation of Go declarations from C source code</h3> + +<p> +The Go version of <code>gcc</code> supports automatically generating +Go declarations from C code. The facility is rather awkward at present, +and a better mechanism is under development. + +<p> +Compile your C code as usual, but replace <code>-c</code> with +<code>-S -ggo</code>. The result will be an assembler file +with a <code>.s</code> extension. This assembler file will contain +comments beginning with #GO. Those comments are declarations in the Go +language for the C types, variables and functions declared in the C code. +C types which can not be represented in Go will contain the string INVALID. +Unsupported macro definitions will be recorded as <code>unknowndefine</code>, +and uses of <code>#undef</code> will be recorded as <code>undef</code>. +So it is very approximately possible to get Go code by running + +<pre> +gcc -S -ggo foo.c +grep '#GO' foo.s | grep -v INVALID | grep -v unknowndefine | grep -v undef > foo.go +</pre> + +<p> +This procedure is full of unstated caveats and restrictions and we make no +guarantee that it will not change in the future. It is more useful as a +starting point for real Go code than as a regular procedure. + +<h2 id="RTEMS_Port">RTEMS Port</h2> +<p> +The <code>gccgo</code> compiler has been ported to <a href="http://www.rtems.com/"> +<code>RTEMS</code></a>. <code>RTEMS</code> is a real-time executive +that provides a high performance environment for embedded applications +on a range of processors and embedded hardware. The current <code>gccgo</code> +port is for x86. The goal is to extend the port to most of the +<a href="http://www.rtems.org/wiki/index.php/SupportedCPUs"> +architectures supported by <code>RTEMS</code></a>. For more information on the port, +as well as instructions on how to install it, please see this +<a href="http://www.rtems.com/wiki/index.php/GCCGoRTEMS"><code>RTEMS</code> Wiki page</a>. diff --git a/doc/go-logo-black.png b/doc/go-logo-black.png Binary files differnew file mode 100644 index 000000000..29be31943 --- /dev/null +++ b/doc/go-logo-black.png diff --git a/doc/go-logo-blue.png b/doc/go-logo-blue.png Binary files differnew file mode 100644 index 000000000..b9eac2727 --- /dev/null +++ b/doc/go-logo-blue.png diff --git a/doc/go-logo-white.png b/doc/go-logo-white.png Binary files differnew file mode 100644 index 000000000..4011069eb --- /dev/null +++ b/doc/go-logo-white.png diff --git a/doc/go_faq.html b/doc/go_faq.html new file mode 100644 index 000000000..aeed53795 --- /dev/null +++ b/doc/go_faq.html @@ -0,0 +1,1496 @@ +<!-- FAQ --> + +<h2 id="Origins">Origins</h2> + +<h3 id="What_is_the_purpose_of_the_project"> +What is the purpose of the project?</h3> + +<p> +No major systems language has emerged in over a decade, but over that time +the computing landscape has changed tremendously. There are several trends: +</p> + +<ul> +<li> +Computers are enormously quicker but software development is not faster. +<li> +Dependency management is a big part of software development today but the +“header files” of languages in the C tradition are antithetical to clean +dependency analysis—and fast compilation. +<li> +There is a growing rebellion against cumbersome type systems like those of +Java and C++, pushing people towards dynamically typed languages such as +Python and JavaScript. +<li> +Some fundamental concepts such as garbage collection and parallel computation +are not well supported by popular systems languages. +<li> +The emergence of multicore computers has generated worry and confusion. +</ul> + +<p> +We believe it's worth trying again with a new language, a concurrent, +garbage-collected language with fast compilation. Regarding the points above: +</p> + +<ul> +<li> +It is possible to compile a large Go program in a few seconds on a single computer. +<li> +Go provides a model for software construction that makes dependency +analysis easy and avoids much of the overhead of C-style include files and +libraries. +<li> +Go's type system has no hierarchy, so no time is spent defining the +relationships between types. Also, although Go has static types the language +attempts to make types feel lighter weight than in typical OO languages. +<li> +Go is fully garbage-collected and provides fundamental support for +concurrent execution and communication. +<li> +By its design, Go proposes an approach for the construction of system +software on multicore machines. +</ul> + +<h3 id="What_is_the_origin_of_the_name"> +What is the origin of the name?</h3> + +<p> +“Ogle” would be a good name for a Go debugger. +</p> + +<h3 id="Whats_the_origin_of_the_mascot"> +What's the origin of the mascot?</h3> + +<p> +The mascot and logo were designed by +<a href="http://reneefrench.blogspot.com">Renée French</a>, who also designed +<a href="http://plan9.bell-labs.com/plan9/glenda.html">Glenda</a>, +the Plan 9 bunny. +The gopher is derived from one she used for an <a href="http://wfmu.org/">WFMU</a> +T-shirt design some years ago. +The logo and mascot are covered by the +<a href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0</a> +license. +</p> + +<h3 id="What_kind_of_a_name_is_6g"> +What kind of a name is 6g?</h3> + +<p> +The <code>6g</code> (and <code>8g</code> and <code>5g</code>) compiler is named in the +tradition of the Plan 9 C compilers, described in +<a href="http://plan9.bell-labs.com/sys/doc/compiler.html"> +http://plan9.bell-labs.com/sys/doc/compiler.html</a> +(see the table in section 2). + +<code>6</code> is the architecture letter for amd64 (or x86-64, if you prefer), while +<code>g</code> stands for Go. +</p> + +<h3 id="history"> +What is the history of the project?</h3> +<p> +Robert Griesemer, Rob Pike and Ken Thompson started sketching the +goals for a new language on the white board on September 21, 2007. +Within a few days the goals had settled into a plan to do something +and a fair idea of what it would be. Design continued part-time in +parallel with unrelated work. By January 2008, Ken had started work +on a compiler with which to explore ideas; it generated C code as its +output. By mid-year the language had become a full-time project and +had settled enough to attempt a production compiler. In May 2008, +Ian Taylor independently started on a GCC front end for Go using the +draft specification. Russ Cox joined in late 2008 and helped move the language +and libraries from prototype to reality. +</p> + +<p> +Go became a public open source project on November 10, 2009. +Many people from the community have contributed ideas, discussions, and code. +</p> + +<h3 id="creating_a_new_language"> +Why are you creating a new language?</h3> +<p> +Go was born out of frustration with existing languages and +environments for systems programming. Programming had become too +difficult and the choice of languages was partly to blame. One had to +choose either efficient compilation, efficient execution, or ease of +programming; all three were not available in the same mainstream +language. Programmers who could were choosing ease over +safety and efficiency by moving to dynamically typed languages such as +Python and JavaScript rather than C++ or, to a lesser extent, Java. +</p> + +<p> +Go is an attempt to combine the ease of programming of an interpreted, +dynamically typed +language with the efficiency and safety of a statically typed, compiled language. +It also aims to be modern, with support for networked and multicore +computing. Finally, it is intended to be <i>fast</i>: it should take +at most a few seconds to build a large executable on a single computer. +To meet these goals required addressing a number of +linguistic issues: an expressive but lightweight type system; +concurrency and garbage collection; rigid dependency specification; +and so on. These cannot be addressed well by libraries or tools; a new +language was called for. +</p> + +<h3 id="ancestors"> +What are Go's ancestors?</h3> +<p> +Go is mostly in the C family (basic syntax), +with significant input from the Pascal/Modula/Oberon +family (declarations, packages), +plus some ideas from languages +inspired by Tony Hoare's CSP, +such as Newsqueak and Limbo (concurrency). +However, it is a new language across the board. +In every respect the language was designed by thinking +about what programmers do and how to make programming, at least the +kind of programming we do, more effective, which means more fun. +</p> + +<h3 id="principles"> +What are the guiding principles in the design?</h3> +<p> +Programming today involves too much bookkeeping, repetition, and +clerical work. As Dick Gabriel says, “Old programs read +like quiet conversations between a well-spoken research worker and a +well-studied mechanical colleague, not as a debate with a compiler. +Who'd have guessed sophistication bought such noise?” +The sophistication is worthwhile—no one wants to go back to +the old languages—but can it be more quietly achieved? +</p> +<p> +Go attempts to reduce the amount of typing in both senses of the word. +Throughout its design, we have tried to reduce clutter and +complexity. There are no forward declarations and no header files; +everything is declared exactly once. Initialization is expressive, +automatic, and easy to use. Syntax is clean and light on keywords. +Stuttering (<code>foo.Foo* myFoo = new(foo.Foo)</code>) is reduced by +simple type derivation using the <code>:=</code> +declare-and-initialize construct. And perhaps most radically, there +is no type hierarchy: types just <i>are</i>, they don't have to +announce their relationships. These simplifications allow Go to be +expressive yet comprehensible without sacrificing, well, sophistication. +</p> +<p> +Another important principle is to keep the concepts orthogonal. +Methods can be implemented for any type; structures represent data while +interfaces represent abstraction; and so on. Orthogonality makes it +easier to understand what happens when things combine. +</p> + +<h2 id="Usage">Usage</h2> + +<h3 id="Is_Google_using_go_internally"> Is Google using Go internally?</h3> + +<p> +Yes. There are now several Go programs deployed in +production inside Google. For instance, the server behind +<a href="http://golang.org">http://golang.org</a> is a Go program; +in fact it's just the <a href="/cmd/godoc"><code>godoc</code></a> +document server running in a production configuration. +</p> + +<h3 id="Do_Go_programs_link_with_Cpp_programs"> +Do Go programs link with C/C++ programs?</h3> + +<p> +There are two Go compiler implementations, <code>6g</code> and friends, +generically called <code>gc</code>, and <code>gccgo</code>. +<code>Gc</code> uses a different calling convention and linker and can +therefore only be linked with C programs using the same convention. +There is such a C compiler but no C++ compiler. +<code>Gccgo</code> is a GCC front-end that can, with care, be linked with +GCC-compiled C or C++ programs. +</p> + +<p> +The <a href="/cmd/cgo/">cgo</a> program provides the mechanism for a +“foreign function interface” to allow safe calling of +C libraries from Go code. SWIG extends this capability to C++ libraries. +</p> + + +<h3 id="Does_Go_support_Google_protocol_buffers"> +Does Go support Google's protocol buffers?</h3> + +<p> +A separate open source project provides the necessary compiler plugin and library. +It is available at +<a href="http://code.google.com/p/goprotobuf/">http://code.google.com/p/goprotobuf/</a> +</p> + + +<h3 id="Can_I_translate_the_Go_home_page"> +Can I translate the Go home page into another language?</h3> + +<p> +Absolutely. We encourage developers to make Go Language sites in their own languages. +However, if you choose to add the Google logo or branding to your site +(it does not appear on <a href="http://golang.org/">golang.org</a>), +you will need to abide by the guidelines at +<a href="http://www.google.com/permissions/guidelines.html">http://www.google.com/permissions/guidelines.html</a> +</p> + +<h2 id="Design">Design</h2> + +<h3 id="unicode_identifiers"> +What's up with Unicode identifiers?</h3> + +<p> +It was important to us to extend the space of identifiers from the +confines of ASCII. Go's rule—identifier characters must be +letters or digits as defined by Unicode—is simple to understand +and to implement but has restrictions. Combining characters are +excluded by design, for instance. +Until there +is an agreed external definition of what an identifier might be, +plus a definition of canonicalization of identifiers that guarantees +no ambiguity, it seemed better to keep combining characters out of +the mix. Thus we have a simple rule that can be expanded later +without breaking programs, one that avoids bugs that would surely arise +from a rule that admits ambiguous identifiers. +</p> + +<p> +On a related note, since an exported identifier must begin with an +upper-case letter, identifiers created from “letters” +in some languages can, by definition, not be exported. For now the +only solution is to use something like <code>X日本語</code>, which +is clearly unsatisfactory; we are considering other options. The +case-for-visibility rule is unlikely to change however; it's one +of our favorite features of Go. +</p> + +<h3 id="Why_doesnt_Go_have_feature_X">Why does Go not have feature X?</h3> + +<p> +Every language contains novel features and omits someone's favorite +feature. Go was designed with an eye on felicity of programming, speed of +compilation, orthogonality of concepts, and the need to support features +such as concurrency and garbage collection. Your favorite feature may be +missing because it doesn't fit, because it affects compilation speed or +clarity of design, or because it would make the fundamental system model +too difficult. +</p> + +<p> +If it bothers you that Go is missing feature <var>X</var>, +please forgive us and investigate the features that Go does have. You might find that +they compensate in interesting ways for the lack of <var>X</var>. +</p> + +<h3 id="generics"> +Why does Go not have generic types?</h3> +<p> +Generics may well be added at some point. We don't feel an urgency for +them, although we understand some programmers do. +</p> + +<p> +Generics are convenient but they come at a cost in +complexity in the type system and run-time. We haven't yet found a +design that gives value proportionate to the complexity, although we +continue to think about it. Meanwhile, Go's built-in maps and slices, +plus the ability to use the empty interface to construct containers +(with explicit unboxing) mean in many cases it is possible to write +code that does what generics would enable, if less smoothly. +</p> + +<p> +This remains an open issue. +</p> + +<h3 id="exceptions"> +Why does Go not have exceptions?</h3> +<p> +We believe that coupling exceptions to a control +structure, as in the <code>try-catch-finally</code> idiom, results in +convoluted code. It also tends to encourage programmers to label +too many ordinary errors, such as failing to open a file, as +exceptional. +</p> + +<p> +Go takes a different approach. For plain error handling, Go's multi-value +returns make it easy to report an error without overloading the return value. +<a href="http://blog.golang.org/2011/07/error-handling-and-go.html">A +canonical error type, coupled +with Go's other features</a>, makes error +handling pleasant but quite different from that in other languages. +</p> + +<p> +Go also has a couple +of built-in functions to signal and recover from truly exceptional +conditions. The recovery mechanism is executed only as part of a +function's state being torn down after an error, which is sufficient +to handle catastrophe but requires no extra control structures and, +when used well, can result in clean error-handling code. +</p> + +<p> +See the <a href="http://blog.golang.org/2010/08/defer-panic-and-recover.html">Defer, Panic, and Recover</a> article for details. +</p> + +<h3 id="assertions"> +Why does Go not have assertions?</h3> + +<p> +Go doesn't provide assertions. They are undeniably convenient, but our +experience has been that programmers use them as a crutch to avoid thinking +about proper error handling and reporting. Proper error handling means that +servers continue operation after non-fatal errors instead of crashing. +Proper error reporting means that errors are direct and to the point, +saving the programmer from interpreting a large crash trace. Precise +errors are particularly important when the programmer seeing the errors is +not familiar with the code. +</p> + +<p> +The same arguments apply to the use of <code>assert()</code> in test programs. Proper +error handling means letting other tests run after one has failed, so +that the person debugging the failure gets a complete picture of what is +wrong. It is more useful for a test to report that +<code>isPrime</code> gives the wrong answer for 2, 3, 5, and 7 (or for +2, 4, 8, and 16) than to report that <code>isPrime</code> gives the wrong +answer for 2 and therefore no more tests were run. The programmer who +triggers the test failure may not be familiar with the code that fails. +Time invested writing a good error message now pays off later when the +test breaks. +</p> + +<p> +In testing, if the amount of extra code required to write +good errors seems repetitive and overwhelming, it might work better as a +table-driven test instead. +Go has excellent support for data structure literals. +</p> + +<p> +We understand that this is a point of contention. There are many things in +the Go language and libraries that differ from modern practices, simply +because we feel it's sometimes worth trying a different approach. +</p> + +<h3 id="csp"> +Why build concurrency on the ideas of CSP?</h3> +<p> +Concurrency and multi-threaded programming have a reputation +for difficulty. We believe the problem is due partly to complex +designs such as pthreads and partly to overemphasis on low-level details +such as mutexes, condition variables, and memory barriers. +Higher-level interfaces enable much simpler code, even if there are still +mutexes and such under the covers. +</p> + +<p> +One of the most successful models for providing high-level linguistic support +for concurrency comes from Hoare's Communicating Sequential Processes, or CSP. +Occam and Erlang are two well known languages that stem from CSP. +Go's concurrency primitives derive from a different part of the family tree +whose main contribution is the powerful notion of channels as first class objects. +</p> + +<h3 id="goroutines"> +Why goroutines instead of threads?</h3> +<p> +Goroutines are part of making concurrency easy to use. The idea, which has +been around for a while, is to multiplex independently executing +functions—coroutines—onto a set of threads. +When a coroutine blocks, such as by calling a blocking system call, +the run-time automatically moves other coroutines on the same operating +system thread to a different, runnable thread so they won't be blocked. +The programmer sees none of this, which is the point. +The result, which we call goroutines, can be very cheap: unless they spend a lot of time +in long-running system calls, they cost little more than the memory +for the stack, which is just a few kilobytes. +</p> + +<p> +To make the stacks small, Go's run-time uses segmented stacks. A newly +minted goroutine is given a few kilobytes, which is almost always enough. +When it isn't, the run-time allocates (and frees) extension segments automatically. +The overhead averages about three cheap instructions per function call. +It is practical to create hundreds of thousands of goroutines in the same +address space. If goroutines were just threads, system resources would +run out at a much smaller number. +</p> + +<h3 id="atomic_maps"> +Why are map operations not defined to be atomic?</h3> + +<p> +After long discussion it was decided that the typical use of maps did not require +safe access from multiple threads, and in those cases where it did, the map was +probably part of some larger data structure or computation that was already +synchronized. Therefore requiring that all map operations grab a mutex would slow +down most programs and add safety to few. This was not an easy decision, +however, since it means uncontrolled map access can crash the program. +</p> + +<p> +The language does not preclude atomic map updates. When required, such +as when hosting an untrusted program, the implementation could interlock +map access. +</p> + +<h2 id="types">Types</h2> + +<h3 id="Is_Go_an_object-oriented_language"> +Is Go an object-oriented language?</h3> + +<p> +Yes and no. Although Go has types and methods and allows an +object-oriented style of programming, there is no type hierarchy. +The concept of “interface” in Go provides a different approach that +we believe is easy to use and in some ways more general. There are +also ways to embed types in other types to provide something +analogous—but not identical—to subclassing. +Moreover, methods in Go are more general than in C++ or Java: +they can be defined for any sort of data, not just structs. +</p> + +<p> +Also, the lack of type hierarchy makes “objects” in Go feel much more +lightweight than in languages such as C++ or Java. +</p> + +<h3 id="How_do_I_get_dynamic_dispatch_of_methods"> +How do I get dynamic dispatch of methods?</h3> + +<p> +The only way to have dynamically dispatched methods is through an +interface. Methods on structs or other types are always resolved statically. +</p> + +<h3 id="inheritance"> +Why is there no type inheritance?</h3> +<p> +Object-oriented programming, at least in the best-known languages, +involves too much discussion of the relationships between types, +relationships that often could be derived automatically. Go takes a +different approach. +</p> + +<p> +Rather than requiring the programmer to declare ahead of time that two +types are related, in Go a type automatically satisfies any interface +that specifies a subset of its methods. Besides reducing the +bookkeeping, this approach has real advantages. Types can satisfy +many interfaces at once, without the complexities of traditional +multiple inheritance. +Interfaces can be very lightweight—an interface with +one or even zero methods can express a useful concept. +Interfaces can be added after the fact if a new idea comes along +or for testing—without annotating the original types. +Because there are no explicit relationships between types +and interfaces, there is no type hierarchy to manage or discuss. +</p> + +<p> +It's possible to use these ideas to construct something analogous to +type-safe Unix pipes. For instance, see how <code>fmt.Fprintf</code> +enables formatted printing to any output, not just a file, or how the +<code>bufio</code> package can be completely separate from file I/O, +or how the <code>crypto</code> packages stitch together block and +stream ciphers. All these ideas stem from a single interface +(<code>io.Writer</code>) representing a single method +(<code>Write</code>). And that's only scratching the surface. +</p> + +<p> +It takes some getting used to but this implicit style of type +dependency is one of the most productive things about Go. +</p> + +<h3 id="methods_on_basics"> +Why is <code>len</code> a function and not a method?</h3> +<p> +We debated this issue but decided +implementing <code>len</code> and friends as functions was fine in practice and +didn't complicate questions about the interface (in the Go type sense) +of basic types. +</p> + +<h3 id="overloading"> +Why does Go not support overloading of methods and operators?</h3> +<p> +Method dispatch is simplified if it doesn't need to do type matching as well. +Experience with other languages told us that having a variety of +methods with the same name but different signatures was occasionally useful +but that it could also be confusing and fragile in practice. Matching only by name +and requiring consistency in the types was a major simplifying decision +in Go's type system. +</p> + +<p> +Regarding operator overloading, it seems more a convenience than an absolute +requirement. Again, things are simpler without it. +</p> + +<h3 id="implements_interface"> +Why doesn't Go have "implements" declarations?</h3> + +<p> +A Go type satisfies an interface by implementing the methods of that interface, +nothing more. This property allows interfaces to be defined and used without +having to modify existing code. It enables a kind of "duck typing" that +promotes separation of concerns and improves code re-use, and makes it easier +to build on patterns that emerge as the code develops. +The semantics of interfaces is one of the main reasons for Go's nimble, +lightweight feel. +</p> + +<p> +See the <a href="#inheritance">question on type inheritance</a> for more detail. +</p> + +<h3 id="guarantee_satisfies_interface"> +How can I guarantee my type satisfies an interface?</h3> + +<p> +You can ask the compiler to check that the type <code>T</code> implements the +interface <code>I</code> by attempting an assignment: +</p> + +<pre> +type T struct{} +var _ I = T{} +</pre> + +<p> +If <code>T</code> doesn't implement <code>I</code>, the mistake will be caught +at compile time. +</p> + +<p> +If you wish the users of an interface to explicitly declare that they implement +it, you can add a method with a descriptive name to the interface's method set. +For example: +</p> + +<pre> +type Fooer interface { + Foo() + ImplementsFooer() +} +</pre> + +<p> +A type must then implement the <code>ImplementsFooer</code> method to be a +<code>Fooer</code>, clearly documenting the fact and announcing it in +<a href="/cmd/godoc/">godoc</a>'s output. +</p> + +<pre> +type Bar struct{} +func (b Bar) ImplementsFooer() {} +func (b Bar) Foo() {} +</pre> + +<p> +Most code doesn't make use of such constraints, since they limit the utility of +the interface idea. Sometimes, though, they're necessary to resolve ambiguities +among similar interfaces. +</p> + +<h3 id="t_and_equal_interface"> +Why doesn't type T satisfy the Equal interface?</h3> + +<p> +Consider this simple interface to represent an object that can compare +itself with another value: +</p> + +<pre> +type Equaler interface { + Equal(Equaler) bool +} +</pre> + +<p> +and this type, <code>T</code>: +</p> + +<pre> +type T int +func (t T) Equal(u T) bool { return t == u } // does not satisfy Equaler +</pre> + +<p> +Unlike the analogous situation in some polymorphic type systems, +<code>T</code> does not implement <code>Equaler</code>. +The argument type of <code>T.Equal</code> is <code>T</code>, +not literally the required type <code>Equaler</code>. +</p> + +<p> +In Go, the type system does not promote the argument of +<code>Equal</code>; that is the programmer's responsibility, as +illustrated by the type <code>T2</code>, which does implement +<code>Equaler</code>: +</p> + +<pre> +type T2 int +func (t T2) Equal(u Equaler) bool { return t == u.(T2) } // satisfies Equaler +</pre> + +<p> +Even this isn't like other type systems, though, because in Go <em>any</em> +type that satisfies <code>Equaler</code> could be passed as the +argument to <code>T2.Equal</code>, and at run time we must +check that the argument is of type <code>T2</code>. +Some languages arrange to make that guarantee at compile time. +</p> + +<p> +A related example goes the other way: +</p> + +<pre> +type Opener interface { + Open(name) Reader +} + +func (t T3) Open() *os.File +</pre> + +<p> +In Go, <code>T3</code> does not satisfy <code>Opener</code>, +although it might in another language. +</p> + +<p> +While it is true that Go's type system does less for the programmer +in such cases, the lack of subtyping makes the rules about +interface satisfaction very easy to state: are the function's names +and signatures exactly those of the interface? +Go's rule is also easy to implement efficiently. +We feel these benefits offset the lack of +automatic type promotion. Should Go one day adopt some form of generic +typing, we expect there would be a way to express the idea of these +examples and also have them be statically checked. +</p> + +<h3 id="convert_slice_of_interface"> +Can I convert a []T to an []interface{}?</h3> + +<p> +Not directly because they do not have the same representation in memory. +It is necessary to copy the elements individually to the destination +slice. This example converts a slice of <code>int</code> to a slice of +<code>interface{}</code>: +</p> + +<pre> +t := []int{1, 2, 3, 4} +s := make([]interface{}, len(t)) +for i, v := range t { + s[i] = v +} +</pre> + +<h3 id="unions"> +Why are there no untagged unions, as in C?</h3> + +<p> +Untagged unions would violate Go's memory safety +guarantees. +</p> + +<h3 id="variant_types"> +Why does Go not have variant types?</h3> + +<p> +Variant types, also known as algebraic types, provide a way to specify +that a value might take one of a set of other types, but only those +types. A common example in systems programming would specify that an +error is, say, a network error, a security error or an application +error and allow the caller to discriminate the source of the problem +by examining the type of the error. Another example is a syntax tree +in which each node can be a different type: declaration, statement, +assignment and so on. +</p> + +<p> +We considered adding variant types to Go, but after discussion +decided to leave them out because they overlap in confusing ways +with interfaces. What would happen if the elements of a variant type +were themselves interfaces? +</p> + +<p> +Also, some of what variant types address is already covered by the +language. The error example is easy to express using an interface +value to hold the error and a type switch to discriminate cases. The +syntax tree example is also doable, although not as elegantly. +</p> + +<h2 id="values">Values</h2> + +<h3 id="conversions"> +Why does Go not provide implicit numeric conversions?</h3> +<p> +The convenience of automatic conversion between numeric types in C is +outweighed by the confusion it causes. When is an expression unsigned? +How big is the value? Does it overflow? Is the result portable, independent +of the machine on which it executes? +It also complicates the compiler; “the usual arithmetic conversions” +are not easy to implement and inconsistent across architectures. +For reasons of portability, we decided to make things clear and straightforward +at the cost of some explicit conversions in the code. +The definition of constants in Go—arbitrary precision values free +of signedness and size annotations—ameliorates matters considerably, +though. +</p> + +<p> +A related detail is that, unlike in C, <code>int</code> and <code>int64</code> +are distinct types even if <code>int</code> is a 64-bit type. The <code>int</code> +type is generic; if you care about how many bits an integer holds, Go +encourages you to be explicit. +</p> + +<h3 id="builtin_maps"> +Why are maps built in?</h3> +<p> +The same reason strings are: they are such a powerful and important data +structure that providing one excellent implementation with syntactic support +makes programming more pleasant. We believe that Go's implementation of maps +is strong enough that it will serve for the vast majority of uses. +If a specific application can benefit from a custom implementation, it's possible +to write one but it will not be as convenient syntactically; this seems a reasonable tradeoff. +</p> + +<h3 id="map_keys"> +Why don't maps allow structs and arrays as keys?</h3> +<p> +Map lookup requires an equality operator, which structs and arrays do not implement. +They don't implement equality because equality is not well defined on such types; +there are multiple considerations involving shallow vs. deep comparison, pointer vs. +value comparison, how to deal with recursive structures, and so on. +We may revisit this issue—and implementing equality for structs and arrays +will not invalidate any existing programs—but without a clear idea of what +equality of structs and arrays should mean, it was simpler to leave it out for now. +</p> + +<h3 id="references"> +Why are maps, slices, and channels references while arrays are values?</h3> +<p> +There's a lot of history on that topic. Early on, maps and channels +were syntactically pointers and it was impossible to declare or use a +non-pointer instance. Also, we struggled with how arrays should work. +Eventually we decided that the strict separation of pointers and +values made the language harder to use. Introducing reference types, +including slices to handle the reference form of arrays, resolved +these issues. Reference types add some regrettable complexity to the +language but they have a large effect on usability: Go became a more +productive, comfortable language when they were introduced. +</p> + +<h2 id="Writing_Code">Writing Code</h2> + +<h3 id="How_are_libraries_documented"> +How are libraries documented?</h3> + +<p> +There is a program, <code>godoc</code>, written in Go, that extracts +package documentation from the source code. It can be used on the +command line or on the web. An instance is running at +<a href="http://golang.org/pkg/">http://golang.org/pkg/</a>. +In fact, <code>godoc</code> implements the full site at +<a href="http://golang.org/">http://golang.org/</a>. +</p> + +<h3 id="Is_there_a_Go_programming_style_guide"> +Is there a Go programming style guide?</h3> + +<p> +Eventually, there may be a small number of rules to guide things +like naming, layout, and file organization. +The document <a href="effective_go.html">Effective Go</a> +contains some style advice. +More directly, the program <code>gofmt</code> is a pretty-printer +whose purpose is to enforce layout rules; it replaces the usual +compendium of do's and don'ts that allows interpretation. +All the Go code in the repository has been run through <code>gofmt</code>. +</p> + +<h3 id="How_do_I_submit_patches_to_the_Go_libraries"> +How do I submit patches to the Go libraries?</h3> + +<p> +The library sources are in <code>go/src/pkg</code>. +If you want to make a significant change, please discuss on the mailing list before embarking. +</p> + +<p> +See the document +<a href="contribute.html">Contributing to the Go project</a> +for more information about how to proceed. +</p> + +<h2 id="Pointers">Pointers and Allocation</h2> + +<h3 id="pass_by_value"> +When are function parameters passed by value?</h3> + +<p> +Everything in Go is passed by value. A function always gets a copy of the +thing being passed, as if there were an assignment statement assigning the +value to the parameter. For instance, copying a pointer value makes a copy of +the pointer, not the data it points to. +</p> + +<p> +Map and slice values behave like pointers; they are descriptors that +contain pointers to the underlying map or slice data. Copying a map or +slice value doesn't copy the data it points to. Copying an interface value +makes a copy of the thing stored in the interface value. If the interface +value holds a struct, copying the interface value makes a copy of the +struct. If the interface value holds a pointer, copying the interface value +makes a copy of the pointer, but again not the data it points to. +</p> + +<h3 id="methods_on_values_or_pointers"> +Should I define methods on values or pointers?</h3> + +<pre> +func (s *MyStruct) pointerMethod() { } // method on pointer +func (s MyStruct) valueMethod() { } // method on value +</pre> + +<p> +For programmers unaccustomed to pointers, the distinction between these +two examples can be confusing, but the situation is actually very simple. +When defining a method on a type, the receiver (<code>s</code> in the above +example) behaves exactly as if it were an argument to the method. +Whether to define the receiver as a value or as a pointer is the same +question, then, as whether a function argument should be a value or +a pointer. +There are several considerations. +</p> + +<p> +First, and most important, does the method need to modify the +receiver? +If it does, the receiver <em>must</em> be a pointer. +(Slices and maps are reference types, so their story is a little +more subtle, but for instance to change the length of a slice +in a method the receiver must still be a pointer.) +In the examples above, if <code>pointerMethod</code> modifies +the fields of <code>s</code>, +the caller will see those changes, but <code>valueMethod</code> +is called with a copy of the caller's argument (that's the definition +of passing a value), so changes it makes will be invisible to the caller. +</p> + +<p> +By the way, pointer receivers are identical to the situation in Java, +although in Java the pointers are hidden under the covers; it's Go's +value receivers that are unusual. +</p> + +<p> +Second is the consideration of efficiency. If the receiver is large, +a big <code>struct</code> for instance, it will be much cheaper to +use a pointer receiver. +</p> + +<p> +Next is consistency. If some of the methods of the type must have +pointer receivers, the rest should too, so the method set is +consistent regardless of how the type is used. +See the section on <a href="#different_method_sets">method sets</a> +for details. +</p> + +<p> +For types such as basic types, slices, and small <code>structs</code>, +a value receiver is very cheap so unless the semantics of the method +requires a pointer, a value receiver is efficient and clear. +</p> + + +<h3 id="new_and_make"> +What's the difference between new and make?</h3> + +<p> +In short: <code>new</code> allocates memory, <code>make</code> initializes +the slice, map, and channel types. +</p> + +<p> +See the <a href="/doc/effective_go.html#allocation_new">relevant section +of Effective Go</a> for more details. +</p> + +<h3 id="q_int_sizes"> +Why is <code>int</code> 32 bits on 64 bit machines?</h3> + +<p> +The sizes of <code>int</code> and <code>uint</code> are implementation-specific +but the same as each other on a given platform. +The 64 bit Go compilers (both 6g and gccgo) use a 32 bit representation for +<code>int</code>. Code that relies on a particular +size of value should use an explicitly sized type, like <code>int64</code>. +On the other hand, floating-point scalars and complex +numbers are always sized: <code>float32</code>, <code>complex64</code>, +etc., because programmers should be aware of precision when using +floating-point numbers. +The default size of a floating-point constant is <code>float64</code>. +</p> + +<h3 id="stack_or_heap"> +How do I know whether a variable is allocated on the heap or the stack?</h3> + +<p> +From a correctness standpoint, you don't need to know. +Each variable in Go exists as long as there are references to it. +The storage location chosen by the implementation is irrelevant to the +semantics of the language. +</p> + +<p> +The storage location does have an effect on writing efficient programs. +When possible, the Go compilers will allocate variables that are +local to a function in that function's stack frame. However, if the +compiler cannot prove that the variable is not referenced after the +function returns, then the compiler must allocate the variable on the +garbage-collected heap to avoid dangling pointer errors. +</p> + +<p> +In the current compilers, the analysis is crude: if a variable has its address +taken, that variable is allocated on the heap. We are working to improve this +analysis so that more data is kept on the stack. +</p> + +<h2 id="Concurrency">Concurrency</h2> + +<h3 id="What_operations_are_atomic_What_about_mutexes"> +What operations are atomic? What about mutexes?</h3> + +<p> +We haven't fully defined it all yet, but some details about atomicity are +available in the <a href="go_mem.html">Go Memory Model specification</a>. +</p> + +<p> +Regarding mutexes, the <a href="/pkg/sync">sync</a> +package implements them, but we hope Go programming style will +encourage people to try higher-level techniques. In particular, consider +structuring your program so that only one goroutine at a time is ever +responsible for a particular piece of data. +</p> + +<p> +Do not communicate by sharing memory. Instead, share memory by communicating. +</p> + +<p> +See the <a href="/doc/codewalk/sharemem/">Share Memory By Communicating</a> code walk and its <a href="http://blog.golang.org/2010/07/share-memory-by-communicating.html">associated article</a> for a detailed discussion of this concept. +</p> + +<h3 id="Why_no_multi_CPU"> +Why doesn't my multi-goroutine program use multiple CPUs?</h3> + +<p> +Under the gc compilers you must set <code>GOMAXPROCS</code> to allow the +run-time support to utilise more than one OS thread. Under <code>gccgo</code> an OS +thread will be created for each goroutine, and <code>GOMAXPROCS</code> is +effectively equal to the number of running goroutines. +</p> + +<p> +Programs that perform concurrent computation should benefit from an increase in +<code>GOMAXPROCS</code>. (See the <a +href="http://golang.org/pkg/runtime/#GOMAXPROCS"><code>runtime</code> package's +documentation</a>.) +</p> + +<h3 id="Why_GOMAXPROCS"> +Why does using <code>GOMAXPROCS</code> > 1 sometimes make my program +slower?</h3> + +<p> +(This is specific to the gc compilers. See above.) +</p> + +<p> +It depends on the nature of your program. +Programs that contain several goroutines that spend a lot of time +communicating on channels will experience performance degradation when using +multiple OS threads. This is because of the significant context-switching +penalty involved in sending data between threads. +</p> + +<p> +Go's goroutine scheduler is not as good as it needs to be. In future, it +should recognize such cases and optimize its use of OS threads. For now, +<code>GOMAXPROCS</code> should be set on a per-application basis. +</p> + +<h2 id="Functions_methods">Functions and Methods</h2> + +<h3 id="different_method_sets"> +Why do T and *T have different method sets?</h3> + +<p> +From the <a href="http://golang.org/doc/go_spec.html#Types">Go Spec</a>: +</p> + +<blockquote> +The method set of any other named type <code>T</code> consists of all methods +with receiver type <code>T</code>. The method set of the corresponding pointer +type <code>*T</code> is the set of all methods with receiver <code>*T</code> or +<code>T</code> (that is, it also contains the method set of <code>T</code>). +</blockquote> + +<p> +If an interface value contains a pointer <code>*T</code>, +a method call can obtain a value by dereferencing the pointer, +but if an interface value contains a value <code>T</code>, +there is no useful way for a method call to obtain a pointer. +</p> + +<p> +If not for this restriction, this code: +</p> + +<pre> +var buf bytes.Buffer +io.Copy(buf, os.Stdin) +</pre> + +<p> +would copy standard input into a <i>copy</i> of <code>buf</code>, +not into <code>buf</code> itself. +This is almost never the desired behavior. +</p> + +<h3 id="closures_and_goroutines"> +Why am I confused by the way my closures behave as goroutines?</h3> + +<p> +Some confusion may arise when using closures with concurrency. +Consider the following program: +</p> + +<pre> +func main() { + done := make(chan bool) + + values := []string{ "a", "b", "c" } + for _, v := range values { + go func() { + fmt.Println(v) + done <- true + }() + } + + // wait for all goroutines to complete before exiting + for _ = range values { + <-done + } +} +</pre> + +<p> +One might mistakenly expect to see <code>a, b, c</code> as the output. +What you'll probably see instead is <code>c, c, c</code>. This is because +each closure shares the same variable <code>v</code>. Each closure prints the +value of <code>v</code> at the time <code>fmt.Println</code> is executed, +rather than the value of <code>v</code> when the goroutine was launched. +</p> + +<p> +To bind the value of <code>v</code> to each closure as they are launched, one +could modify the inner loop to read: +</p> + +<pre> + for _, v := range values { + go func(<b>u</b> string) { + fmt.Println(<b>u</b>) + done <- true + }(<b>v</b>) + } +</pre> + +<p> +In this example, the value of <code>v</code> is passed as an argument to the +anonymous function. That value is then accessible inside the function as +the variable <code>u</code>. +</p> + +<h2 id="Control_flow">Control flow</h2> + +<h3 id="Does_Go_have_a_ternary_form"> +Does Go have the <code>?:</code> operator?</h3> + +<p> +There is no ternary form in Go. You may use the following to achieve the same +result: +</p> + +<pre> +if expr { + n = trueVal +} else { + n = falseVal +} +</pre> + +<h2 id="Packages_Testing">Packages and Testing</h2> + +<h3 id="How_do_I_create_a_multifile_package"> +How do I create a multifile package?</h3> + +<p> +Put all the source files for the package in a directory by themselves. +Source files can refer to items from different files at will; there is +no need for forward declarations or a header file. +</p> + +<p> +Other than being split into multiple files, the package will compile and test +just like a single-file package. +</p> + +<h3 id="How_do_I_write_a_unit_test"> +How do I write a unit test?</h3> + +<p> +Create a new file ending in <code>_test.go</code> in the same directory +as your package sources. Inside that file, <code>import "testing"</code> +and write functions of the form +</p> + +<pre> +func TestFoo(t *testing.T) { + ... +} +</pre> + +<p> +Run <code>gotest</code> in that directory. +That script finds the <code>Test</code> functions, +builds a test binary, and runs it. +</p> + +<p>See the <a href="/doc/code.html">How to Write Go Code</a> document for more details.</p> + + +<h2 id="Implementation">Implementation</h2> + +<h3 id="What_compiler_technology_is_used_to_build_the_compilers"> +What compiler technology is used to build the compilers?</h3> + +<p> +<code>Gccgo</code> has a C++ front-end with a recursive descent parser coupled to the +standard GCC back end. <code>Gc</code> is written in C using +<code>yacc</code>/<code>bison</code> for the parser. +Although it's a new program, it fits in the Plan 9 C compiler suite +(<a href="http://plan9.bell-labs.com/sys/doc/compiler.html">http://plan9.bell-labs.com/sys/doc/compiler.html</a>) +and uses a variant of the Plan 9 loader to generate ELF binaries. +</p> + +<p> +We considered writing <code>6g</code>, the original Go compiler, in Go itself but +elected not to do so because of the difficulties of bootstrapping and +especially of open source distribution—you'd need a Go compiler to +set up a Go environment. <code>Gccgo</code>, which came later, makes it possible to +consider writing a compiler in Go, which might well happen. (Go would be a +fine language in which to implement a compiler; a native lexer and +parser are already available in <a href="/pkg/go/"><code>/pkg/go</code></a>.) +</p> + +<p> +We also considered using LLVM for <code>6g</code> but we felt it was too large and +slow to meet our performance goals. +</p> + +<h3 id="How_is_the_run_time_support_implemented"> +How is the run-time support implemented?</h3> + +<p> +Again due to bootstrapping issues, the run-time code is mostly in C (with a +tiny bit of assembler) although Go is capable of implementing most of +it now. <code>Gccgo</code>'s run-time support uses <code>glibc</code>. +<code>Gc</code> uses a custom library to keep the footprint under +control; it is +compiled with a version of the Plan 9 C compiler that supports +segmented stacks for goroutines. +Work is underway to provide the same stack management in +<code>gccgo</code>. +</p> + +<h3 id="Why_is_my_trivial_program_such_a_large_binary"> +Why is my trivial program such a large binary?</h3> + +<p> +The gc tool chain (<code>5l</code>, <code>6l</code>, and <code>8l</code>) only +generate statically linked binaries. All Go binaries therefore include the Go +run-time, along with the run-time type information necessary to support dynamic +type checks, reflection, and even panic-time stack traces. +</p> + +<p> +A trivial C "hello, world" program compiled and linked statically using gcc +on Linux is around 750 kB. An equivalent Go program is around 1.1 MB, but +that includes more powerful run-time support. We believe that with some effort +the size of Go binaries can be reduced. +</p> + +<h3 id="unused_variables_and_imports"> +Can I stop these complaints about my unused variable/import?</h3> + +<p> +The presence of an unused variable may indicate a bug, while +unused imports just slow down compilation. +Accumulate enough unused imports in your code tree and +things can get very slow. +For these reasons, Go allows neither. +</p> + +<p> +When developing code, it's common to create these situations +temporarily and it can be annoying to have to edit them out before the +program will compile. +</p> + +<p> +Some have asked for a compiler option to turn those checks off +or at least reduce them to warnings. +Such an option has not been added, though, +because compiler options should not affect the semantics of the +language and because the Go compiler does not report warnings, only +errors that prevent compilation. +</p> + +<p> +There are two reasons for having no warnings. First, if it's worth +complaining about, it's worth fixing in the code. (And if it's not +worth fixing, it's not worth mentioning.) Second, having the compiler +generate warnings encourages the implementation to warn about weak +cases that can make compilation noisy, masking real errors that +<em>should</em> be fixed. +</p> + +<p> +It's easy to address the situation, though. Use the blank identifier +to let unused things persist while you're developing. +</p> + +<pre> +import "unused" + +// This declaration marks the import as used by referencing an +// item from the package. +var _ = unused.Item // TODO: Delete before committing! + +func main() { + debugData := debug.Profile() + _ = debugData // Used only during debugging. + .... +} +</pre> + +<h2 id="Performance">Performance</h2> + +<h3 id="Why_does_Go_perform_badly_on_benchmark_x"> +Why does Go perform badly on benchmark X?</h3> + +<p> +One of Go's design goals is to approach the performance of C for comparable +programs, yet on some benchmarks it does quite poorly, including several +in <a href="/test/bench/">test/bench</a>. The slowest depend on libraries +for which versions of comparable performance are not available in Go. +For instance, pidigits depends on a multi-precision math package, and the C +versions, unlike Go's, use <a href="http://gmplib.org/">GMP</a> (which is +written in optimized assembler). +Benchmarks that depend on regular expressions (regex-dna, for instance) are +essentially comparing Go's stopgap <a href="/pkg/regexp">regexp package</a> to +mature, highly optimized regular expression libraries like PCRE. +</p> + +<p> +Benchmark games are won by extensive tuning and the Go versions of most +of the benchmarks need attention. If you measure comparable C +and Go programs (reverse-complement is one example), you'll see the two +languages are much closer in raw performance than this suite would +indicate. +</p> + +<p> +Still, there is room for improvement. The compilers are good but could be +better, many libraries need major performance work, and the garbage collector +isn't fast enough yet (even if it were, taking care not to generate unnecessary +garbage can have a huge effect). +</p> + +<p> +In any case, Go can often be very competitive. See the blog post about +<a href="http://blog.golang.org/2011/06/profiling-go-programs.html">profiling +Go programs</a> for an informative example. + +<h2 id="change_from_c">Changes from C</h2> + +<h3 id="different_syntax"> +Why is the syntax so different from C?</h3> +<p> +Other than declaration syntax, the differences are not major and stem +from two desires. First, the syntax should feel light, without too +many mandatory keywords, repetition, or arcana. Second, the language +has been designed to be easy to analyze +and can be parsed without a symbol table. This makes it much easier +to build tools such as debuggers, dependency analyzers, automated +documentation extractors, IDE plug-ins, and so on. C and its +descendants are notoriously difficult in this regard. +</p> + +<h3 id="declarations_backwards"> +Why are declarations backwards?</h3> +<p> +They're only backwards if you're used to C. In C, the notion is that a +variable is declared like an expression denoting its type, which is a +nice idea, but the type and expression grammars don't mix very well and +the results can be confusing; consider function pointers. Go mostly +separates expression and type syntax and that simplifies things (using +prefix <code>*</code> for pointers is an exception that proves the rule). In C, +the declaration +</p> +<pre> + int* a, b; +</pre> +<p> +declares <code>a</code> to be a pointer but not <code>b</code>; in Go +</p> +<pre> + var a, b *int; +</pre> +<p> +declares both to be pointers. This is clearer and more regular. +Also, the <code>:=</code> short declaration form argues that a full variable +declaration should present the same order as <code>:=</code> so +</p> +<pre> + var a uint64 = 1; +</pre> +has the same effect as +<pre> + a := uint64(1); +</pre> +<p> +Parsing is also simplified by having a distinct grammar for types that +is not just the expression grammar; keywords such as <code>func</code> +and <code>chan</code> keep things clear. +</p> + +<p> +See the article about +<a href="http://blog.golang.org/2010/07/gos-declaration-syntax.html">Go's Declaration Syntax</a> +for more details. +</p> + +<h3 id="no_pointer_arithmetic"> +Why is there no pointer arithmetic?</h3> +<p> +Safety. Without pointer arithmetic it's possible to create a +language that can never derive an illegal address that succeeds +incorrectly. Compiler and hardware technology have advanced to the +point where a loop using array indices can be as efficient as a loop +using pointer arithmetic. Also, the lack of pointer arithmetic can +simplify the implementation of the garbage collector. +</p> + +<h3 id="inc_dec"> +Why are <code>++</code> and <code>--</code> statements and not expressions? And why postfix, not prefix?</h3> +<p> +Without pointer arithmetic, the convenience value of pre- and postfix +increment operators drops. By removing them from the expression +hierarchy altogether, expression syntax is simplified and the messy +issues around order of evaluation of <code>++</code> and <code>--</code> +(consider <code>f(i++)</code> and <code>p[i] = q[++i]</code>) +are eliminated as well. The simplification is +significant. As for postfix vs. prefix, either would work fine but +the postfix version is more traditional; insistence on prefix arose +with the STL, a library for a language whose name contains, ironically, a +postfix increment. +</p> + +<h3 id="semicolons"> +Why are there braces but no semicolons? And why can't I put the opening +brace on the next line?</h3> +<p> +Go uses brace brackets for statement grouping, a syntax familiar to +programmers who have worked with any language in the C family. +Semicolons, however, are for parsers, not for people, and we wanted to +eliminate them as much as possible. To achieve this goal, Go borrows +a trick from BCPL: the semicolons that separate statements are in the +formal grammar but are injected automatically, without lookahead, by +the lexer at the end of any line that could be the end of a statement. +This works very well in practice but has the effect that it forces a +brace style. For instance, the opening brace of a function cannot +appear on a line by itself. +</p> + +<p> +Some have argued that the lexer should do lookahead to permit the +brace to live on the next line. We disagree. Since Go code is meant +to be formatted automatically by +<a href="http://golang.org/cmd/gofmt/"><code>gofmt</code></a>, +<i>some</i> style must be chosen. That style may differ from what +you've used in C or Java, but Go is a new language and +<code>gofmt</code>'s style is as good as any other. More +important—much more important—the advantages of a single, +programmatically mandated format for all Go programs greatly outweigh +any perceived disadvantages of the particular style. +Note too that Go's style means that an interactive implementation of +Go can use the standard syntax one line at a time without special rules. +</p> + +<h3 id="garbage_collection"> +Why do garbage collection? Won't it be too expensive?</h3> +<p> +One of the biggest sources of bookkeeping in systems programs is +memory management. We feel it's critical to eliminate that +programmer overhead, and advances in garbage collection +technology in the last few years give us confidence that we can +implement it with low enough overhead and no significant +latency. (The current implementation is a plain mark-and-sweep +collector but a replacement is in the works.) +</p> + +<p> +Another point is that a large part of the difficulty of concurrent +and multi-threaded programming is memory management; +as objects get passed among threads it becomes cumbersome +to guarantee they become freed safely. +Automatic garbage collection makes concurrent code far easier to write. +Of course, implementing garbage collection in a concurrent environment is +itself a challenge, but meeting it once rather than in every +program helps everyone. +</p> + +<p> +Finally, concurrency aside, garbage collection makes interfaces +simpler because they don't need to specify how memory is managed across them. +</p> + +<p> +On the topic of performance, keep in mind that Go gives the programmer +considerable control over memory layout and allocation, much more than +is typical in garbage-collected languages. A careful programmer can reduce +the garbage collection overhead dramatically by using the language well; +see the article about +<a href="http://blog.golang.org/2011/06/profiling-go-programs.html">profiling +Go programs</a> for a worked example, including a demonstration of Go's +profiling tools. +</p> diff --git a/doc/go_for_cpp_programmers.html b/doc/go_for_cpp_programmers.html new file mode 100644 index 000000000..7168f1d05 --- /dev/null +++ b/doc/go_for_cpp_programmers.html @@ -0,0 +1,707 @@ +<!-- Go For C++ Programmers --> + +<p> +Go is a systems programming language intended to be a general-purpose +systems language, like C++. +These are some notes on Go for experienced C++ programmers. This +document discusses the differences between Go and C++, and says little +to nothing about the similarities. + +<p> +For a more general introduction to Go, see the +<a href="go_tutorial.html">Go tutorial</a> and +<a href="effective_go.html">Effective Go</a>. + +<p> +For a detailed description of the Go language, see the +<a href="go_spec.html">Go spec</a>. + +<h2 id="Conceptual_Differences">Conceptual Differences</h2> + +<ul> +<li>Go does not have classes with constructors or destructors. + Instead of class methods, a class inheritance hierarchy, + and virtual functions, Go provides <em>interfaces</em>, which are + <a href="#Interfaces">discussed in more detail below</a>. + Interfaces are also used where C++ uses templates. + +<li>Go uses garbage collection. It is not necessary (or possible) + to release memory explicitly. The garbage collection is (intended to be) + incremental and highly efficient on modern processors. + +<li>Go has pointers but not pointer arithmetic. You cannot + use a pointer variable to walk through the bytes of a string. + +<li>Arrays in Go are first class values. When an array is used as a + function parameter, the function receives a copy of the array, not + a pointer to it. However, in practice functions often use slices + for parameters; slices hold pointers to underlying arrays. Slices + are <a href="#Slices">discussed further below</a>. + +<li>Strings are provided by the language. They may not be changed once they + have been created. + +<li>Hash tables are provided by the language. They are called maps. + +<li>Separate threads of execution, and communication channels between + them, are provided by the language. This + is <a href="#Goroutines">discussed further below</a>. + +<li>Certain types (maps and channels, described further below) + are passed by reference, not by value. That is, passing a map to a + function does not copy the map, and if the function changes the map + the change will be seen by the caller. In C++ terms, one can + think of these as being reference types. + +<li>Go does not use header files. Instead, each source file is part of a + defined <em>package</em>. When a package defines an object + (type, constant, variable, function) with a name starting with an + upper case letter, that object is visible to any other file which + imports that package. + +<li>Go does not support implicit type conversion. Operations that mix + different types require casts (called conversions in Go). + +<li>Go does not support function overloading and does not support user + defined operators. + +<li>Go does not support <code>const</code> or <code>volatile</code> qualifiers. + +<li>Go uses <code>nil</code> for invalid pointers, where C++ uses + <code>NULL</code> or simply <code>0</code>. +</ul> + +<h2 id="Syntax">Syntax</h2> + +<p> +The declaration syntax is reversed compared to C++. You write the name +followed by the type. Unlike in C++, the syntax for a type does not match +the way in which the variable is used. Type declarations may be read +easily from left to right. + +<pre> +<b>Go C++</b> +var v1 int // int v1; +var v2 string // const std::string v2; (approximately) +var v3 [10]int // int v3[10]; +var v4 []int // int* v4; (approximately) +var v5 struct { f int } // struct { int f; } v5; +var v6 *int // int* v6; (but no pointer arithmetic) +var v7 map[string]int // unordered_map<string, int>* v7; (approximately) +var v8 func(a int) int // int (*v8)(int a); +</pre> + +<p> +Declarations generally take the form of a keyword followed by the name +of the object being declared. The keyword is one of <code>var</code>, +<code>func</code>, +<code>const</code>, or <code>type</code>. Method declarations are a minor +exception in that +the receiver appears before the name of the object being declared; see +the <a href="#Interfaces">discussion of interfaces</a>. + +<p> +You can also use a keyword followed by a series of declarations in +parentheses. + +<pre> +var ( + i int + m float64 +) +</pre> + +<p> +When declaring a function, you must either provide a name for each parameter +or not provide a name for any parameter; you can't omit some names +and provide others. You may group several names with the same type: + +<pre> +func f(i, j, k int, s, t string) +</pre> + +<p> +A variable may be initialized when it is declared. When this is done, +specifying the type is permitted but not required. When the type is +not specified, the type of the variable is the type of the +initialization expression. + +<pre> +var v = *p +</pre> + +<p> +See also the <a href="#Constants">discussion of constants, below</a>. +If a variable is not initialized explicitly, the type must be specified. +In that case it will be +implicitly initialized to the type's zero value (0, nil, etc.). There are no +uninitialized variables in Go. + +<p> +Within a function, a short declaration syntax is available with +<code>:=</code> . + +<pre> +v1 := v2 +</pre> + +<p> +This is equivalent to + +<pre> +var v1 = v2 +</pre> + +<p> +Go permits multiple assignments, which are done in parallel. + +<pre> +i, j = j, i // Swap i and j. +</pre> + +<p> +Functions may have multiple return values, indicated by a list in +parentheses. The returned values can be stored by assignment +to a list of variables. + +<pre> +func f() (i int, j int) { ... } +v1, v2 = f() +</pre> + +<p> +Go code uses very few semicolons in practice. Technically, all Go +statements are terminated by a semicolon. However, Go treats the end +of a non-blank line as a semicolon unless the line is clearly +incomplete (the exact rules are +in <a href="go_spec.html#Semicolons">the language specification</a>). +A consequence of this is that in some cases Go does not permit you to +use a line break. For example, you may not write +<pre> +func g() +{ // INVALID +} +</pre> +A semicolon will be inserted after <code>g()</code>, causing it to be +a function declaration rather than a function definition. Similarly, +you may not write +<pre> +if x { +} +else { // INVALID +} +</pre> +A semicolon will be inserted after the <code>}</code> preceding +the <code>else</code>, causing a syntax error. + +<p> +Since semicolons do end statements, you may continue using them as in +C++. However, that is not the recommended style. Idiomatic Go code +omits unnecessary semicolons, which in practice is all of them other +than the initial <code>for</code> loop clause and cases where you want several +short statements on a single line. + +<p> +While we're on the topic, we recommend that rather than worry about +semicolons and brace placement, you format your code with +the <code>gofmt</code> program. That will produce a single standard +Go style, and let you worry about your code rather than your +formatting. While the style may initially seem odd, it is as good as +any other style, and familiarity will lead to comfort. + +<p> +When using a pointer to a struct, you use <code>.</code> instead +of <code>-></code>. +Thus syntactically speaking a structure and a pointer to a structure +are used in the same way. + +<pre> +type myStruct struct { i int } +var v9 myStruct // v9 has structure type +var p9 *myStruct // p9 is a pointer to a structure +f(v9.i, p9.i) +</pre> + +<p> +Go does not require parentheses around the condition of a <code>if</code> +statement, or the expressions of a <code>for</code> statement, or the value of a +<code>switch</code> statement. On the other hand, it does require curly braces +around the body of an <code>if</code> or <code>for</code> statement. + +<pre> +if a < b { f() } // Valid +if (a < b) { f() } // Valid (condition is a parenthesized expression) +if (a < b) f() // INVALID +for i = 0; i < 10; i++ {} // Valid +for (i = 0; i < 10; i++) {} // INVALID +</pre> + +<p> +Go does not have a <code>while</code> statement nor does it have a +<code>do/while</code> +statement. The <code>for</code> statement may be used with a single condition, +which makes it equivalent to a <code>while</code> statement. Omitting the +condition entirely is an endless loop. + +<p> +Go permits <code>break</code> and <code>continue</code> to specify a label. +The label must +refer to a <code>for</code>, <code>switch</code>, or <code>select</code> +statement. + +<p> +In a <code>switch</code> statement, <code>case</code> labels do not fall +through. You can +make them fall through using the <code>fallthrough</code> keyword. This applies +even to adjacent cases. + +<pre> +switch i { +case 0: // empty case body +case 1: + f() // f is not called when i == 0! +} +</pre> + +<p> +But a <code>case</code> can have multiple values. + +<pre> +switch i { +case 0, 1: + f() // f is called if i == 0 || i == 1. +} +</pre> + +<p> +The values in a <code>case</code> need not be constants—or even integers; +any type +that supports the equality comparison operator, such as strings or +pointers, can be used—and if the <code>switch</code> +value is omitted it defaults to <code>true</code>. + +<pre> +switch { +case i < 0: + f1() +case i == 0: + f2() +case i > 0: + f3() +} +</pre> + +<p> +The <code>++</code> and <code>--</code> operators may only be used in +statements, not in expressions. +You cannot write <code>c = *p++</code>. <code>*p++</code> is parsed as +<code>(*p)++</code>. + +<p> +The <code>defer</code> statement may be used to call a function after +the function containing the <code>defer</code> statement returns. + +<pre> +fd := open("filename") +defer close(fd) // fd will be closed when this function returns. +</pre> + +<h2 id="Constants">Constants </h2> + +<p> +In Go constants may be <i>untyped</i>. This applies even to constants +named with a <code>const</code> declaration, if no +type is given in the declaration and the initializer expression uses only +untyped constants. +A value derived from an untyped constant becomes typed when it +is used within a context that +requires a typed value. This permits constants to be used relatively +freely without requiring general implicit type conversion. + +<pre> +var a uint +f(a + 1) // untyped numeric constant "1" becomes typed as uint +</pre> + +<p> +The language does not impose any limits on the size of an untyped +numeric constant or constant expression. A limit is only applied when +a constant is used where a type is required. + +<pre> +const huge = 1 << 100 +f(huge >> 98) +</pre> + +<p> +Go does not support enums. Instead, you can use the special name +<code>iota</code> in a single <code>const</code> declaration to get a +series of increasing +value. When an initialization expression is omitted for a <code>const</code>, +it reuses the preceding expression. + +<pre> +const ( + red = iota // red == 0 + blue // blue == 1 + green // green == 2 +) +</pre> + +<h2 id="Slices">Slices</h2> + +<p> +A slice is conceptually a struct with three fields: a +pointer to an array, a length, and a capacity. +Slices support +the <code>[]</code> operator to access elements of the underlying array. +The builtin +<code>len</code> function returns the +length of the slice. The builtin <code>cap</code> function returns the +capacity. + +<p> +Given an array, or another slice, a new slice is created via +<code>a[I:J]</code>. This +creates a new slice which refers to <code>a</code>, starts at +index <code>I</code>, and ends before index +<code>J</code>. It has length <code>J - I</code>. +The new slice refers to the same array +to which <code>a</code> +refers. That is, changes made using the new slice may be seen using +<code>a</code>. The +capacity of the new slice is simply the capacity of <code>a</code> minus +<code>I</code>. The capacity +of an array is the length of the array. You may also assign an array pointer +to a variable of slice type; given <code>var s []int; var a[10] int</code>, +the assignment <code>s = &a</code> is equivalent to +<code>s = a[0:len(a)]</code>. + +<p> +What this means is that Go uses slices for some cases where C++ uses pointers. +If you create a value of type <code>[100]byte</code> (an array of 100 bytes, +perhaps a +buffer) and you want to pass it to a function without copying it, you should +declare the function parameter to have type <code>[]byte</code>, and pass the +address +of the array. Unlike in C++, it is not +necessary to pass the length of the buffer; it is efficiently accessible via +<code>len</code>. + +<p> +The slice syntax may also be used with a string. It returns a new string, +whose value is a substring of the original string. +Because strings are immutable, string slices can be implemented +without allocating new storage for the slices's contents. + +<h2 id="Making_values">Making values</h2> + +<p> +Go has a builtin function <code>new</code> which takes a type and +allocates space +on the heap. The allocated space will be zero-initialized for the type. +For example, <code>new(int)</code> allocates a new int on the heap, +initializes it with the value <code>0</code>, +and returns its address, which has type <code>*int</code>. +Unlike in C++, <code>new</code> is a function, not an operator; +<code>new int</code> is a syntax error. + +<p> +Map and channel values must be allocated using the builtin function +<code>make</code>. +A variable declared with map or channel type without an initializer will be +automatically initialized to <code>nil</code>. +Calling <code>make(map[int]int)</code> returns a newly allocated value of +type <code>map[int]int</code>. +Note that <code>make</code> returns a value, not a pointer. This is +consistent with +the fact that map and channel values are passed by reference. Calling +<code>make</code> with +a map type takes an optional argument which is the expected capacity of the +map. Calling <code>make</code> with a channel type takes an optional +argument which sets the +buffering capacity of the channel; the default is 0 (unbuffered). + +<p> +The <code>make</code> function may also be used to allocate a slice. +In this case it +allocates memory for the underlying array and returns a slice referring to it. +There is one required argument, which is the number of elements in the slice. +A second, optional, argument is the capacity of the slice. For example, +<code>make([]int, 10, 20)</code>. This is identical to +<code>new([20]int)[0:10]</code>. Since +Go uses garbage collection, the newly allocated array will be discarded +sometime after there are no references to the returned slice. + +<h2 id="Interfaces">Interfaces</h2> + +<p> +Where C++ provides classes, subclasses and templates, +Go provides interfaces. A +Go interface is similar to a C++ pure abstract class: a class with no +data members, with methods which are all pure virtual. However, in +Go, any type which provides the methods named in the interface may be +treated as an implementation of the interface. No explicitly declared +inheritance is required. The implementation of the interface is +entirely separate from the interface itself. + +<p> +A method looks like an ordinary function definition, except that it +has a <em>receiver</em>. The receiver is similar to +the <code>this</code> pointer in a C++ class method. + +<pre> +type myType struct { i int } +func (p *myType) get() int { return p.i } +</pre> + +<p> +This declares a method <code>get</code> associated with <code>myType</code>. +The receiver is named <code>p</code> in the body of the function. + +<p> +Methods are defined on named types. If you convert the value +to a different type, the new value will have the methods of the new type, +not the old type. + +<p> +You may define methods on a builtin type by declaring a new named type +derived from it. The new type is distinct from the builtin type. + +<pre> +type myInteger int +func (p myInteger) get() int { return int(p) } // Conversion required. +func f(i int) { } +var v myInteger +// f(v) is invalid. +// f(int(v)) is valid; int(v) has no defined methods. +</pre> + +<p> +Given this interface: + +<pre> +type myInterface interface { + get() int + set(i int) +} +</pre> + +<p> +we can make <code>myType</code> satisfy the interface by adding + +<pre> +func (p *myType) set(i int) { p.i = i } +</pre> + +<p> +Now any function which takes <code>myInterface</code> as a parameter +will accept a +variable of type <code>*myType</code>. + +<pre> +func getAndSet(x myInterface) {} +func f1() { + var p myType + getAndSet(&p) +} +</pre> + +<p> +In other words, if we view <code>myInterface</code> as a C++ pure abstract +base +class, defining <code>set</code> and <code>get</code> for +<code>*myType</code> made <code>*myType</code> automatically +inherit from <code>myInterface</code>. A type may satisfy multiple interfaces. + +<p> +An anonymous field may be used to implement something much like a C++ child +class. + +<pre> +type myChildType struct { myType; j int } +func (p *myChildType) get() int { p.j++; return p.myType.get() } +</pre> + +<p> +This effectively implements <code>myChildType</code> as a child of +<code>myType</code>. + +<pre> +func f2() { + var p myChildType + getAndSet(&p) +} +</pre> + +<p> +The <code>set</code> method is effectively inherited from +<code>myChildType</code>, because +methods associated with the anonymous field are promoted to become methods +of the enclosing type. In this case, because <code>myChildType</code> has an +anonymous field of type <code>myType</code>, the methods of +<code>myType</code> also become methods of <code>myChildType</code>. +In this example, the <code>get</code> method was +overridden, and the <code>set</code> method was inherited. + +<p> +This is not precisely the same as a child class in C++. +When a method of an anonymous field is called, +its receiver is the field, not the surrounding struct. +In other words, methods on anonymous fields are not virtual functions. +When you want the equivalent of a virtual function, use an interface. + +<p> +A variable which has an interface type may be converted to have a +different interface type using a special construct called a type assertion. +This is implemented dynamically +at run time, like C++ <code>dynamic_cast</code>. Unlike +<code>dynamic_cast</code>, there does +not need to be any declared relationship between the two interfaces. + +<pre> +type myPrintInterface interface { + print() +} +func f3(x myInterface) { + x.(myPrintInterface).print() // type assertion to myPrintInterface +} +</pre> + +<p> +The conversion to <code>myPrintInterface</code> is entirely dynamic. +It will +work as long as the underlying type of x (the <em>dynamic type</em>) defines +a <code>print</code> method. + +<p> +Because the conversion is dynamic, it may be used to implement generic +programming similar to templates in C++. This is done by +manipulating values of the minimal interface. + +<pre> +type Any interface { } +</pre> + +<p> +Containers may be written in terms of <code>Any</code>, but the caller +must unbox using a type assertion to recover +values of the contained type. As the typing is dynamic rather +than static, there is no equivalent of the way that a C++ template may +inline the relevant operations. The operations are fully type-checked +at run time, but all operations will involve a function call. + +<pre> +type iterator interface { + get() Any + set(v Any) + increment() + equal(arg *iterator) bool +} +</pre> + +<h2 id="Goroutines">Goroutines</h2> + +<p> +Go permits starting a new thread of execution (a <em>goroutine</em>) +using the <code>go</code> +statement. The <code>go</code> statement runs a function in a +different, newly created, goroutine. +All goroutines in a single program share the same address space. + +<p> +Internally, goroutines act like coroutines that are multiplexed among +multiple operating system threads. You do not have to worry +about these details. + +<pre> +func server(i int) { + for { + print(i) + sys.sleep(10) + } +} +go server(1) +go server(2) +</pre> + +<p> +(Note that the <code>for</code> statement in the <code>server</code> +function is equivalent to a C++ <code>while (true)</code> loop.) + +<p> +Goroutines are (intended to be) cheap. + +<p> +Function literals (which Go implements as closures) +can be useful with the <code>go</code> statement. + +<pre> +var g int +go func(i int) { + s := 0 + for j := 0; j < i; j++ { s += j } + g = s +}(1000) // Passes argument 1000 to the function literal. +</pre> + +<h2 id="Channels">Channels</h2> + +<p> +Channels are used to communicate between goroutines. Any value may be +sent over a channel. Channels are (intended to be) efficient and +cheap. To send a value on a channel, use <code><-</code> as a binary +operator. To +receive a value on a channel, use <code><-</code> as a unary operator. +When calling +functions, channels are passed by reference. + +<p> +The Go library provides mutexes, but you can also use +a single goroutine with a shared channel. +Here is an example of using a manager function to control access to a +single value. + +<pre> +type cmd struct { get bool; val int } +func manager(ch chan cmd) { + var val int = 0 + for { + c := <- ch + if c.get { c.val = val; ch <- c } + else { val = c.val } + } +} +</pre> + +<p> +In that example the same channel is used for input and output. +This is incorrect if there are multiple goroutines communicating +with the manager at once: a goroutine waiting for a response +from the manager might receive a request from another goroutine +instead. +A solution is to pass in a channel. + +<pre> +type cmd2 struct { get bool; val int; ch <- chan int } +func manager2(ch chan cmd2) { + var val int = 0 + for { + c := <- ch + if c.get { c.ch <- val } + else { val = c.val } + } +} +</pre> + +<p> +To use <code>manager2</code>, given a channel to it: + +<pre> +func f4(ch <- chan cmd2) int { + myCh := make(chan int) + c := cmd2{ true, 0, myCh } // Composite literal syntax. + ch <- c + return <-myCh +} +</pre> diff --git a/doc/go_mem.html b/doc/go_mem.html new file mode 100644 index 000000000..a38828358 --- /dev/null +++ b/doc/go_mem.html @@ -0,0 +1,510 @@ +<!-- The Go Memory Model --> +<!-- subtitle Version of June 10, 2011 --> + +<style> +p.rule { + font-style: italic; +} +span.event { + font-style: italic; +} +</style> + +<h2>Introduction</h2> + +<p> +The Go memory model specifies the conditions under which +reads of a variable in one goroutine can be guaranteed to +observe values produced by writes to the same variable in a different goroutine. +</p> + +<h2>Happens Before</h2> + +<p> +Within a single goroutine, reads and writes must behave +as if they executed in the order specified by the program. +That is, compilers and processors may reorder the reads and writes +executed within a single goroutine only when the reordering +does not change the behavior within that goroutine +as defined by the language specification. +Because of this reordering, the execution order observed +by one goroutine may differ from the order perceived +by another. For example, if one goroutine +executes <code>a = 1; b = 2;</code>, another might observe +the updated value of <code>b</code> before the updated value of <code>a</code>. +</p> + +<p> +To specify the requirements of reads and writes, we define +<i>happens before</i>, a partial order on the execution +of memory operations in a Go program. If event <span class="event">e<sub>1</sub></span> happens +before event <span class="event">e<sub>2</sub></span>, then we say that <span class="event">e<sub>2</sub></span> happens after <span class="event">e<sub>1</sub></span>. +Also, if <span class="event">e<sub>1</sub></span> does not happen before <span class="event">e<sub>2</sub></span> and does not happen +after <span class="event">e<sub>2</sub></span>, then we say that <span class="event">e<sub>1</sub></span> and <span class="event">e<sub>2</sub></span> happen concurrently. +</p> + +<p class="rule"> +Within a single goroutine, the happens-before order is the +order expressed by the program. +</p> + +<p> +A read <span class="event">r</span> of a variable <code>v</code> is <i>allowed</i> to observe a write <span class="event">w</span> to <code>v</code> +if both of the following hold: +</p> + +<ol> +<li><span class="event">w</span> happens before <span class="event">r</span>.</li> +<li>There is no other write <span class="event">w'</span> to <code>v</code> that happens + after <span class="event">w</span> but before <span class="event">r</span>.</li> +</ol> + +<p> +To guarantee that a read <span class="event">r</span> of a variable <code>v</code> observes a +particular write <span class="event">w</span> to <code>v</code>, ensure that <span class="event">w</span> is the only +write <span class="event">r</span> is allowed to observe. +That is, <span class="event">r</span> is <i>guaranteed</i> to observe <span class="event">w</span> if both of the following hold: +</p> + +<ol> +<li><span class="event">w</span> happens before <span class="event">r</span>.</li> +<li>Any other write to the shared variable <code>v</code> +either happens before <span class="event">w</span> or after <span class="event">r</span>.</li> +</ol> + +<p> +This pair of conditions is stronger than the first pair; +it requires that there are no other writes happening +concurrently with <span class="event">w</span> or <span class="event">r</span>. +</p> + +<p> +Within a single goroutine, +there is no concurrency, so the two definitions are equivalent: +a read <span class="event">r</span> observes the value written by the most recent write <span class="event">w</span> to <code>v</code>. +When multiple goroutines access a shared variable <code>v</code>, +they must use synchronization events to establish +happens-before conditions that ensure reads observe the +desired writes. +</p> + +<p> +The initialization of variable <code>v</code> with the zero value +for <code>v</code>'s type behaves as a write in the memory model. +</p> + +<p> +Reads and writes of values larger than a single machine word +behave as multiple machine-word-sized operations in an +unspecified order. +</p> + +<h2>Synchronization</h2> + +<h3>Initialization</h3> + +<p> +Program initialization runs in a single goroutine and +new goroutines created during initialization do not +start running until initialization ends. +</p> + +<p class="rule"> +If a package <code>p</code> imports package <code>q</code>, the completion of +<code>q</code>'s <code>init</code> functions happens before the start of any of <code>p</code>'s. +</p> + +<p class="rule"> +The start of the function <code>main.main</code> happens after +all <code>init</code> functions have finished. +</p> + +<p class="rule"> +The execution of any goroutines created during <code>init</code> +functions happens after all <code>init</code> functions have finished. +</p> + +<h3>Goroutine creation</h3> + +<p class="rule"> +The <code>go</code> statement that starts a new goroutine +happens before the goroutine's execution begins. +</p> + +<p> +For example, in this program: +</p> + +<pre> +var a string + +func f() { + print(a) +} + +func hello() { + a = "hello, world" + go f() +} +</pre> + +<p> +calling <code>hello</code> will print <code>"hello, world"</code> +at some point in the future (perhaps after <code>hello</code> has returned). +</p> + +<h3>Goroutine destruction</h3> + +<p> +The exit of a goroutine is not guaranteed to happen before +any event in the program. For example, in this program: +</p> + +<pre> +var a string + +func hello() { + go func() { a = "hello" }() + print(a) +} +</pre> + +<p> +the assignment to <code>a</code> is not followed by +any synchronization event, so it is not guaranteed to be +observed by any other goroutine. +In fact, an aggressive compiler might delete the entire <code>go</code> statement. +</p> + +<p> +If the effects of a goroutine must be observed by another goroutine, +use a synchronization mechanism such as a lock or channel +communication to establish a relative ordering. +</p> + +<h3>Channel communication</h3> + +<p> +Channel communication is the main method of synchronization +between goroutines. Each send on a particular channel +is matched to a corresponding receive from that channel, +usually in a different goroutine. +</p> + +<p class="rule"> +A send on a channel happens before the corresponding +receive from that channel completes. +</p> + +<p> +This program: +</p> + +<pre> +var c = make(chan int, 10) +var a string + +func f() { + a = "hello, world" + c <- 0 +} + +func main() { + go f() + <-c + print(a) +} +</pre> + +<p> +is guaranteed to print <code>"hello, world"</code>. The write to <code>a</code> +happens before the send on <code>c</code>, which happens before +the corresponding receive on <code>c</code> completes, which happens before +the <code>print</code>. +</p> + +<p class="rule"> +The closing of a channel happens before a receive that returns a zero value +because the channel is closed. +</p> + +<p> +In the previous example, replacing +<code>c <- 0</code> with <code>close(c)</code> +yields a program with the same guaranteed behavior. +</p> + +<p class="rule"> +A receive from an unbuffered channel happens before +the send on that channel completes. +</p> + +<p> +This program (as above, but with the send and receive statements swapped and +using an unbuffered channel): +</p> + +<pre> +var c = make(chan int) +var a string + +func f() { + a = "hello, world" + <-c +} +</pre> + +<pre> +func main() { + go f() + c <- 0 + print(a) +} +</pre> + +<p> +is also guaranteed to print <code>"hello, world"</code>. The write to <code>a</code> +happens before the receive on <code>c</code>, which happens before +the corresponding send on <code>c</code> completes, which happens +before the <code>print</code>. +</p> + +<p> +If the channel were buffered (e.g., <code>c = make(chan int, 1)</code>) +then the program would not be guaranteed to print +<code>"hello, world"</code>. (It might print the empty string; +it cannot print <code>"goodbye, universe"</code>, nor can it crash.) +</p> + +<h3>Locks</h3> + +<p> +The <code>sync</code> package implements two lock data types, +<code>sync.Mutex</code> and <code>sync.RWMutex</code>. +</p> + +<p class="rule"> +For any <code>sync.Mutex</code> or <code>sync.RWMutex</code> variable <code>l</code> and <i>n</i> < <i>m</i>, +the <i>n</i>'th call to <code>l.Unlock()</code> happens before the <i>m</i>'th call to <code>l.Lock()</code> returns. +</p> + +<p> +This program: +</p> + +<pre> +var l sync.Mutex +var a string + +func f() { + a = "hello, world" + l.Unlock() +} + +func main() { + l.Lock() + go f() + l.Lock() + print(a) +} +</pre> + +<p> +is guaranteed to print <code>"hello, world"</code>. +The first call to <code>l.Unlock()</code> (in <code>f</code>) happens +before the second call to <code>l.Lock()</code> (in <code>main</code>) returns, +which happens before the <code>print</code>. +</p> + +<p class="rule"> +For any call to <code>l.RLock</code> on a <code>sync.RWMutex</code> variable <code>l</code>, +there is an <i>n</i> such that the <code>l.RLock</code> happens (returns) after the <i>n</i>'th call to +<code>l.Unlock</code> and the matching <code>l.RUnlock</code> happens +before the <i>n</i>+1'th call to <code>l.Lock</code>. +</p> + +<h3>Once</h3> + +<p> +The <code>sync</code> package provides a safe mechanism for +initialization in the presence of multiple goroutines +through the use of the <code>Once</code> type. +Multiple threads can execute <code>once.Do(f)</code> for a particular <code>f</code>, +but only one will run <code>f()</code>, and the other calls block +until <code>f()</code> has returned. +</p> + +<p class="rule"> +A single call of <code>f()</code> from <code>once.Do(f)</code> happens (returns) before any call of <code>once.Do(f)</code> returns. +</p> + +<p> +In this program: +</p> + +<pre> +var a string +var once sync.Once + +func setup() { + a = "hello, world" +} + +func doprint() { + once.Do(setup) + print(a) +} + +func twoprint() { + go doprint() + go doprint() +} +</pre> + +<p> +calling <code>twoprint</code> causes <code>"hello, world"</code> to be printed twice. +The first call to <code>twoprint</code> runs <code>setup</code> once. +</p> + +<h2>Incorrect synchronization</h2> + +<p> +Note that a read <span class="event">r</span> may observe the value written by a write <span class="event">w</span> +that happens concurrently with <span class="event">r</span>. +Even if this occurs, it does not imply that reads happening after <span class="event">r</span> +will observe writes that happened before <span class="event">w</span>. +</p> + +<p> +In this program: +</p> + +<pre> +var a, b int + +func f() { + a = 1 + b = 2 +} + +func g() { + print(b) + print(a) +} + +func main() { + go f() + g() +} +</pre> + +<p> +it can happen that <code>g</code> prints <code>2</code> and then <code>0</code>. +</p> + +<p> +This fact invalidates a few common idioms. +</p> + +<p> +Double-checked locking is an attempt to avoid the overhead of synchronization. +For example, the <code>twoprint</code> program might be +incorrectly written as: +</p> + +<pre> +var a string +var done bool + +func setup() { + a = "hello, world" + done = true +} + +func doprint() { + if !done { + once.Do(setup) + } + print(a) +} + +func twoprint() { + go doprint() + go doprint() +} +</pre> + +<p> +but there is no guarantee that, in <code>doprint</code>, observing the write to <code>done</code> +implies observing the write to <code>a</code>. This +version can (incorrectly) print an empty string +instead of <code>"hello, world"</code>. +</p> + +<p> +Another incorrect idiom is busy waiting for a value, as in: +</p> + +<pre> +var a string +var done bool + +func setup() { + a = "hello, world" + done = true +} + +func main() { + go setup() + for !done { + } + print(a) +} +</pre> + +<p> +As before, there is no guarantee that, in <code>main</code>, +observing the write to <code>done</code> +implies observing the write to <code>a</code>, so this program could +print an empty string too. +Worse, there is no guarantee that the write to <code>done</code> will ever +be observed by <code>main</code>, since there are no synchronization +events between the two threads. The loop in <code>main</code> is not +guaranteed to finish. +</p> + +<p> +There are subtler variants on this theme, such as this program. +</p> + +<pre> +type T struct { + msg string +} + +var g *T + +func setup() { + t := new(T) + t.msg = "hello, world" + g = t +} + +func main() { + go setup() + for g == nil { + } + print(g.msg) +} +</pre> + +<p> +Even if <code>main</code> observes <code>g != nil</code> and exits its loop, +there is no guarantee that it will observe the initialized +value for <code>g.msg</code>. +</p> + +<p> +In all these examples, the solution is the same: +use explicit synchronization. +</p> diff --git a/doc/go_spec.html b/doc/go_spec.html new file mode 100644 index 000000000..82c7ed419 --- /dev/null +++ b/doc/go_spec.html @@ -0,0 +1,5272 @@ +<!-- title The Go Programming Language Specification --> +<!-- subtitle Version of July 14, 2011 --> + +<!-- +TODO +[ ] need language about function/method calls and parameter passing rules +[ ] last paragraph of #Assignments (constant promotion) should be elsewhere + and mention assignment to empty interface. +[ ] need to say something about "scope" of selectors? +[ ] clarify what a field name is in struct declarations + (struct{T} vs struct {T T} vs struct {t T}) +[ ] need explicit language about the result type of operations +[ ] should probably write something about evaluation order of statements even + though obvious +[ ] review language on implicit dereferencing +[ ] clarify what it means for two functions to be "the same" when comparing them +--> + + +<h2 id="Introduction">Introduction</h2> + +<p> +This is a reference manual for the Go programming language. For +more information and other documents, see <a href="http://golang.org/">http://golang.org</a>. +</p> + +<p> +Go is a general-purpose language designed with systems programming +in mind. It is strongly typed and garbage-collected and has explicit +support for concurrent programming. Programs are constructed from +<i>packages</i>, whose properties allow efficient management of +dependencies. The existing implementations use a traditional +compile/link model to generate executable binaries. +</p> + +<p> +The grammar is compact and regular, allowing for easy analysis by +automatic tools such as integrated development environments. +</p> + +<h2 id="Notation">Notation</h2> +<p> +The syntax is specified using Extended Backus-Naur Form (EBNF): +</p> + +<pre class="grammar"> +Production = production_name "=" [ Expression ] "." . +Expression = Alternative { "|" Alternative } . +Alternative = Term { Term } . +Term = production_name | token [ "…" token ] | Group | Option | Repetition . +Group = "(" Expression ")" . +Option = "[" Expression "]" . +Repetition = "{" Expression "}" . +</pre> + +<p> +Productions are expressions constructed from terms and the following +operators, in increasing precedence: +</p> +<pre class="grammar"> +| alternation +() grouping +[] option (0 or 1 times) +{} repetition (0 to n times) +</pre> + +<p> +Lower-case production names are used to identify lexical tokens. +Non-terminals are in CamelCase. Lexical symbols are enclosed in +double quotes <code>""</code> or back quotes <code>``</code>. +</p> + +<p> +The form <code>a … b</code> represents the set of characters from +<code>a</code> through <code>b</code> as alternatives. The horizontal +ellipis … is also used elsewhere in the spec to informally denote various +enumerations or code snippets that are not further specified. The character … +(as opposed to the three characters <code>...</code>) is not a token of the Go +language. +</p> + +<h2 id="Source_code_representation">Source code representation</h2> + +<p> +Source code is Unicode text encoded in +<a href="http://en.wikipedia.org/wiki/UTF-8">UTF-8</a>. The text is not +canonicalized, so a single accented code point is distinct from the +same character constructed from combining an accent and a letter; +those are treated as two code points. For simplicity, this document +will use the term <i>character</i> to refer to a Unicode code point. +</p> +<p> +Each code point is distinct; for instance, upper and lower case letters +are different characters. +</p> +<p> +Implementation restriction: For compatibility with other tools, a +compiler may disallow the NUL character (U+0000) in the source text. +</p> + +<h3 id="Characters">Characters</h3> + +<p> +The following terms are used to denote specific Unicode character classes: +</p> +<pre class="ebnf"> +newline = /* the Unicode code point U+000A */ . +unicode_char = /* an arbitrary Unicode code point except newline */ . +unicode_letter = /* a Unicode code point classified as "Letter" */ . +unicode_digit = /* a Unicode code point classified as "Decimal Digit" */ . +</pre> + +<p> +In <a href="http://www.unicode.org/versions/Unicode6.0.0/">The Unicode Standard 6.0</a>, +Section 4.5 "General Category" +defines a set of character categories. Go treats +those characters in category Lu, Ll, Lt, Lm, or Lo as Unicode letters, +and those in category Nd as Unicode digits. +</p> + +<h3 id="Letters_and_digits">Letters and digits</h3> + +<p> +The underscore character <code>_</code> (U+005F) is considered a letter. +</p> +<pre class="ebnf"> +letter = unicode_letter | "_" . +decimal_digit = "0" … "9" . +octal_digit = "0" … "7" . +hex_digit = "0" … "9" | "A" … "F" | "a" … "f" . +</pre> + +<h2 id="Lexical_elements">Lexical elements</h2> + +<h3 id="Comments">Comments</h3> + +<p> +There are two forms of comments: +</p> + +<ol> +<li> +<i>Line comments</i> start with the character sequence <code>//</code> +and stop at the end of the line. A line comment acts like a newline. +</li> +<li> +<i>General comments</i> start with the character sequence <code>/*</code> +and continue through the character sequence <code>*/</code>. A general +comment that spans multiple lines acts like a newline, otherwise it acts +like a space. +</li> +</ol> + +<p> +Comments do not nest. +</p> + + +<h3 id="Tokens">Tokens</h3> + +<p> +Tokens form the vocabulary of the Go language. +There are four classes: <i>identifiers</i>, <i>keywords</i>, <i>operators +and delimiters</i>, and <i>literals</i>. <i>White space</i>, formed from +spaces (U+0020), horizontal tabs (U+0009), +carriage returns (U+000D), and newlines (U+000A), +is ignored except as it separates tokens +that would otherwise combine into a single token. Also, a newline or end of file +may trigger the insertion of a <a href="#Semicolons">semicolon</a>. +While breaking the input into tokens, +the next token is the longest sequence of characters that form a +valid token. +</p> + +<h3 id="Semicolons">Semicolons</h3> + +<p> +The formal grammar uses semicolons <code>";"</code> as terminators in +a number of productions. Go programs may omit most of these semicolons +using the following two rules: +</p> + +<ol> +<li> +<p> +When the input is broken into tokens, a semicolon is automatically inserted +into the token stream at the end of a non-blank line if the line's final +token is +</p> +<ul> + <li>an + <a href="#Identifiers">identifier</a> + </li> + + <li>an + <a href="#Integer_literals">integer</a>, + <a href="#Floating-point_literals">floating-point</a>, + <a href="#Imaginary_literals">imaginary</a>, + <a href="#Character_literals">character</a>, or + <a href="#String_literals">string</a> literal + </li> + + <li>one of the <a href="#Keywords">keywords</a> + <code>break</code>, + <code>continue</code>, + <code>fallthrough</code>, or + <code>return</code> + </li> + + <li>one of the <a href="#Operators_and_Delimiters">operators and delimiters</a> + <code>++</code>, + <code>--</code>, + <code>)</code>, + <code>]</code>, or + <code>}</code> + </li> +</ul> +</li> + +<li> +To allow complex statements to occupy a single line, a semicolon +may be omitted before a closing <code>")"</code> or <code>"}"</code>. +</li> +</ol> + +<p> +To reflect idiomatic use, code examples in this document elide semicolons +using these rules. +</p> + + +<h3 id="Identifiers">Identifiers</h3> + +<p> +Identifiers name program entities such as variables and types. +An identifier is a sequence of one or more letters and digits. +The first character in an identifier must be a letter. +</p> +<pre class="ebnf"> +identifier = letter { letter | unicode_digit } . +</pre> +<pre> +a +_x9 +ThisVariableIsExported +αβ +</pre> + +<p> +Some identifiers are <a href="#Predeclared_identifiers">predeclared</a>. +</p> + + +<h3 id="Keywords">Keywords</h3> + +<p> +The following keywords are reserved and may not be used as identifiers. +</p> +<pre class="grammar"> +break default func interface select +case defer go map struct +chan else goto package switch +const fallthrough if range type +continue for import return var +</pre> + +<h3 id="Operators_and_Delimiters">Operators and Delimiters</h3> + +<p> +The following character sequences represent <a href="#Operators">operators</a>, delimiters, and other special tokens: +</p> +<pre class="grammar"> ++ & += &= && == != ( ) +- | -= |= || < <= [ ] +* ^ *= ^= <- > >= { } +/ << /= <<= ++ = := , ; +% >> %= >>= -- ! ... . : + &^ &^= +</pre> + +<h3 id="Integer_literals">Integer literals</h3> + +<p> +An integer literal is a sequence of digits representing an +<a href="#Constants">integer constant</a>. +An optional prefix sets a non-decimal base: <code>0</code> for octal, <code>0x</code> or +<code>0X</code> for hexadecimal. In hexadecimal literals, letters +<code>a-f</code> and <code>A-F</code> represent values 10 through 15. +</p> +<pre class="ebnf"> +int_lit = decimal_lit | octal_lit | hex_lit . +decimal_lit = ( "1" … "9" ) { decimal_digit } . +octal_lit = "0" { octal_digit } . +hex_lit = "0" ( "x" | "X" ) hex_digit { hex_digit } . +</pre> + +<pre> +42 +0600 +0xBadFace +170141183460469231731687303715884105727 +</pre> + +<h3 id="Floating-point_literals">Floating-point literals</h3> +<p> +A floating-point literal is a decimal representation of a +<a href="#Constants">floating-point constant</a>. +It has an integer part, a decimal point, a fractional part, +and an exponent part. The integer and fractional part comprise +decimal digits; the exponent part is an <code>e</code> or <code>E</code> +followed by an optionally signed decimal exponent. One of the +integer part or the fractional part may be elided; one of the decimal +point or the exponent may be elided. +</p> +<pre class="ebnf"> +float_lit = decimals "." [ decimals ] [ exponent ] | + decimals exponent | + "." decimals [ exponent ] . +decimals = decimal_digit { decimal_digit } . +exponent = ( "e" | "E" ) [ "+" | "-" ] decimals . +</pre> + +<pre> +0. +72.40 +072.40 // == 72.40 +2.71828 +1.e+0 +6.67428e-11 +1E6 +.25 +.12345E+5 +</pre> + +<h3 id="Imaginary_literals">Imaginary literals</h3> +<p> +An imaginary literal is a decimal representation of the imaginary part of a +<a href="#Constants">complex constant</a>. +It consists of a +<a href="#Floating-point_literals">floating-point literal</a> +or decimal integer followed +by the lower-case letter <code>i</code>. +</p> +<pre class="ebnf"> +imaginary_lit = (decimals | float_lit) "i" . +</pre> + +<pre> +0i +011i // == 11i +0.i +2.71828i +1.e+0i +6.67428e-11i +1E6i +.25i +.12345E+5i +</pre> + + +<h3 id="Character_literals">Character literals</h3> + +<p> +A character literal represents an <a href="#Constants">integer constant</a>, +typically a Unicode code point, as one or more characters enclosed in single +quotes. Within the quotes, any character may appear except single +quote and newline. A single quoted character represents itself, +while multi-character sequences beginning with a backslash encode +values in various formats. +</p> +<p> +The simplest form represents the single character within the quotes; +since Go source text is Unicode characters encoded in UTF-8, multiple +UTF-8-encoded bytes may represent a single integer value. For +instance, the literal <code>'a'</code> holds a single byte representing +a literal <code>a</code>, Unicode U+0061, value <code>0x61</code>, while +<code>'ä'</code> holds two bytes (<code>0xc3</code> <code>0xa4</code>) representing +a literal <code>a</code>-dieresis, U+00E4, value <code>0xe4</code>. +</p> +<p> +Several backslash escapes allow arbitrary values to be represented +as ASCII text. There are four ways to represent the integer value +as a numeric constant: <code>\x</code> followed by exactly two hexadecimal +digits; <code>\u</code> followed by exactly four hexadecimal digits; +<code>\U</code> followed by exactly eight hexadecimal digits, and a +plain backslash <code>\</code> followed by exactly three octal digits. +In each case the value of the literal is the value represented by +the digits in the corresponding base. +</p> +<p> +Although these representations all result in an integer, they have +different valid ranges. Octal escapes must represent a value between +0 and 255 inclusive. Hexadecimal escapes satisfy this condition +by construction. The escapes <code>\u</code> and <code>\U</code> +represent Unicode code points so within them some values are illegal, +in particular those above <code>0x10FFFF</code> and surrogate halves. +</p> +<p> +After a backslash, certain single-character escapes represent special values: +</p> +<pre class="grammar"> +\a U+0007 alert or bell +\b U+0008 backspace +\f U+000C form feed +\n U+000A line feed or newline +\r U+000D carriage return +\t U+0009 horizontal tab +\v U+000b vertical tab +\\ U+005c backslash +\' U+0027 single quote (valid escape only within character literals) +\" U+0022 double quote (valid escape only within string literals) +</pre> +<p> +All other sequences starting with a backslash are illegal inside character literals. +</p> +<pre class="ebnf"> +char_lit = "'" ( unicode_value | byte_value ) "'" . +unicode_value = unicode_char | little_u_value | big_u_value | escaped_char . +byte_value = octal_byte_value | hex_byte_value . +octal_byte_value = `\` octal_digit octal_digit octal_digit . +hex_byte_value = `\` "x" hex_digit hex_digit . +little_u_value = `\` "u" hex_digit hex_digit hex_digit hex_digit . +big_u_value = `\` "U" hex_digit hex_digit hex_digit hex_digit + hex_digit hex_digit hex_digit hex_digit . +escaped_char = `\` ( "a" | "b" | "f" | "n" | "r" | "t" | "v" | `\` | "'" | `"` ) . +</pre> + +<pre> +'a' +'ä' +'本' +'\t' +'\000' +'\007' +'\377' +'\x07' +'\xff' +'\u12e4' +'\U00101234' +</pre> + + +<h3 id="String_literals">String literals</h3> + +<p> +A string literal represents a <a href="#Constants">string constant</a> +obtained from concatenating a sequence of characters. There are two forms: +raw string literals and interpreted string literals. +</p> +<p> +Raw string literals are character sequences between back quotes +<code>``</code>. Within the quotes, any character is legal except +back quote. The value of a raw string literal is the +string composed of the uninterpreted characters between the quotes; +in particular, backslashes have no special meaning and the string may +span multiple lines. +</p> +<p> +Interpreted string literals are character sequences between double +quotes <code>""</code>. The text between the quotes, +which may not span multiple lines, forms the +value of the literal, with backslash escapes interpreted as they +are in character literals (except that <code>\'</code> is illegal and +<code>\"</code> is legal). The three-digit octal (<code>\</code><i>nnn</i>) +and two-digit hexadecimal (<code>\x</code><i>nn</i>) escapes represent individual +<i>bytes</i> of the resulting string; all other escapes represent +the (possibly multi-byte) UTF-8 encoding of individual <i>characters</i>. +Thus inside a string literal <code>\377</code> and <code>\xFF</code> represent +a single byte of value <code>0xFF</code>=255, while <code>ÿ</code>, +<code>\u00FF</code>, <code>\U000000FF</code> and <code>\xc3\xbf</code> represent +the two bytes <code>0xc3</code> <code>0xbf</code> of the UTF-8 encoding of character +U+00FF. +</p> + +<pre class="ebnf"> +string_lit = raw_string_lit | interpreted_string_lit . +raw_string_lit = "`" { unicode_char | newline } "`" . +interpreted_string_lit = `"` { unicode_value | byte_value } `"` . +</pre> + +<pre> +`abc` // same as "abc" +`\n +\n` // same as "\\n\n\\n" +"\n" +"" +"Hello, world!\n" +"日本語" +"\u65e5本\U00008a9e" +"\xff\u00FF" +</pre> + +<p> +These examples all represent the same string: +</p> + +<pre> +"日本語" // UTF-8 input text +`日本語` // UTF-8 input text as a raw literal +"\u65e5\u672c\u8a9e" // The explicit Unicode code points +"\U000065e5\U0000672c\U00008a9e" // The explicit Unicode code points +"\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e" // The explicit UTF-8 bytes +</pre> + +<p> +If the source code represents a character as two code points, such as +a combining form involving an accent and a letter, the result will be +an error if placed in a character literal (it is not a single code +point), and will appear as two code points if placed in a string +literal. +</p> + + +<h2 id="Constants">Constants</h2> + +<p>There are <i>boolean constants</i>, <i>integer constants</i>, +<i>floating-point constants</i>, <i>complex constants</i>, +and <i>string constants</i>. Integer, floating-point, +and complex constants are +collectively called <i>numeric constants</i>. +</p> + +<p> +A constant value is represented by an +<a href="#Integer_literals">integer</a>, +<a href="#Floating-point_literals">floating-point</a>, +<a href="#Imaginary_literals">imaginary</a>, +<a href="#Character_literals">character</a>, or +<a href="#String_literals">string</a> literal, +an identifier denoting a constant, +a <a href="#Constant_expressions">constant expression</a>, +a <a href="#Conversions">conversion</a> with a result that is a constant, or +the result value of some built-in functions such as +<code>unsafe.Sizeof</code> applied to any value, +<code>cap</code> or <code>len</code> applied to +<a href="#Length_and_capacity">some expressions</a>, +<code>real</code> and <code>imag</code> applied to a complex constant +and <code>complex</code> applied to numeric constants. +The boolean truth values are represented by the predeclared constants +<code>true</code> and <code>false</code>. The predeclared identifier +<a href="#Iota">iota</a> denotes an integer constant. +</p> + +<p> +In general, complex constants are a form of +<a href="#Constant_expressions">constant expression</a> +and are discussed in that section. +</p> + +<p> +Numeric constants represent values of arbitrary precision and do not overflow. +</p> + +<p> +Constants may be <a href="#Types">typed</a> or untyped. +Literal constants, <code>true</code>, <code>false</code>, <code>iota</code>, +and certain <a href="#Constant_expressions">constant expressions</a> +containing only untyped constant operands are untyped. +</p> + +<p> +A constant may be given a type explicitly by a <a href="#Constant_declarations">constant declaration</a> +or <a href="#Conversions">conversion</a>, or implicitly when used in a +<a href="#Variable_declarations">variable declaration</a> or an +<a href="#Assignments">assignment</a> or as an +operand in an <a href="#Expressions">expression</a>. +It is an error if the constant value +cannot be represented as a value of the respective type. +For instance, <code>3.0</code> can be given any integer or any +floating-point type, while <code>2147483648.0</code> (equal to <code>1<<31</code>) +can be given the types <code>float32</code>, <code>float64</code>, or <code>uint32</code> but +not <code>int32</code> or <code>string</code>. +</p> + +<p> +There are no constants denoting the IEEE-754 infinity and not-a-number values, +but the <a href="/pkg/math/"><code>math</code> package</a>'s +<a href="/pkg/math/#Inf">Inf</a>, +<a href="/pkg/math/#NaN">NaN</a>, +<a href="/pkg/math/#IsInf">IsInf</a>, and +<a href="/pkg/math/#IsNaN">IsNaN</a> +functions return and test for those values at run time. +</p> + +<p> +Implementation restriction: A compiler may implement numeric constants by choosing +an internal representation with at least twice as many bits as any machine type; +for floating-point values, both the mantissa and exponent must be twice as large. +</p> + + +<h2 id="Types">Types</h2> + +<p> +A type determines the set of values and operations specific to values of that +type. A type may be specified by a (possibly qualified) <i>type name</i> +(§<a href="#Qualified_identifiers">Qualified identifier</a>, §<a href="#Type_declarations">Type declarations</a>) or a <i>type literal</i>, +which composes a new type from previously declared types. +</p> + +<pre class="ebnf"> +Type = TypeName | TypeLit | "(" Type ")" . +TypeName = QualifiedIdent . +TypeLit = ArrayType | StructType | PointerType | FunctionType | InterfaceType | + SliceType | MapType | ChannelType . +</pre> + +<p> +Named instances of the boolean, numeric, and string types are +<a href="#Predeclared_identifiers">predeclared</a>. +<i>Composite types</i>—array, struct, pointer, function, +interface, slice, map, and channel types—may be constructed using +type literals. +</p> + +<p> +The <i>static type</i> (or just <i>type</i>) of a variable is the +type defined by its declaration. Variables of interface type +also have a distinct <i>dynamic type</i>, which +is the actual type of the value stored in the variable at run-time. +The dynamic type may vary during execution but is always +<a href="#Assignability">assignable</a> +to the static type of the interface variable. For non-interface +types, the dynamic type is always the static type. +</p> + +<p> +Each type <code>T</code> has an <i>underlying type</i>: If <code>T</code> +is a predeclared type or a type literal, the corresponding underlying +type is <code>T</code> itself. Otherwise, <code>T</code>'s underlying type +is the underlying type of the type to which <code>T</code> refers in its +<a href="#Type_declarations">type declaration</a>. +</p> + +<pre> + type T1 string + type T2 T1 + type T3 []T1 + type T4 T3 +</pre> + +<p> +The underlying type of <code>string</code>, <code>T1</code>, and <code>T2</code> +is <code>string</code>. The underlying type of <code>[]T1</code>, <code>T3</code>, +and <code>T4</code> is <code>[]T1</code>. +</p> + +<h3 id="Method_sets">Method sets</h3> +<p> +A type may have a <i>method set</i> associated with it +(§<a href="#Interface_types">Interface types</a>, §<a href="#Method_declarations">Method declarations</a>). +The method set of an <a href="#Interface_types">interface type</a> is its interface. +The method set of any other named type <code>T</code> +consists of all methods with receiver type <code>T</code>. +The method set of the corresponding pointer type <code>*T</code> +is the set of all methods with receiver <code>*T</code> or <code>T</code> +(that is, it also contains the method set of <code>T</code>). +Any other type has an empty method set. +In a method set, each method must have a unique name. +</p> + + +<h3 id="Boolean_types">Boolean types</h3> + +A <i>boolean type</i> represents the set of Boolean truth values +denoted by the predeclared constants <code>true</code> +and <code>false</code>. The predeclared boolean type is <code>bool</code>. + + +<h3 id="Numeric_types">Numeric types</h3> + +<p> +A <i>numeric type</i> represents sets of integer or floating-point values. +The predeclared architecture-independent numeric types are: +</p> + +<pre class="grammar"> +uint8 the set of all unsigned 8-bit integers (0 to 255) +uint16 the set of all unsigned 16-bit integers (0 to 65535) +uint32 the set of all unsigned 32-bit integers (0 to 4294967295) +uint64 the set of all unsigned 64-bit integers (0 to 18446744073709551615) + +int8 the set of all signed 8-bit integers (-128 to 127) +int16 the set of all signed 16-bit integers (-32768 to 32767) +int32 the set of all signed 32-bit integers (-2147483648 to 2147483647) +int64 the set of all signed 64-bit integers (-9223372036854775808 to 9223372036854775807) + +float32 the set of all IEEE-754 32-bit floating-point numbers +float64 the set of all IEEE-754 64-bit floating-point numbers + +complex64 the set of all complex numbers with float32 real and imaginary parts +complex128 the set of all complex numbers with float64 real and imaginary parts + +byte familiar alias for uint8 +</pre> + +<p> +The value of an <i>n</i>-bit integer is <i>n</i> bits wide and represented using +<a href="http://en.wikipedia.org/wiki/Two's_complement">two's complement arithmetic</a>. +</p> + +<p> +There is also a set of predeclared numeric types with implementation-specific sizes: +</p> + +<pre class="grammar"> +uint either 32 or 64 bits +int same size as uint +uintptr an unsigned integer large enough to store the uninterpreted bits of a pointer value +</pre> + +<p> +To avoid portability issues all numeric types are distinct except +<code>byte</code>, which is an alias for <code>uint8</code>. +Conversions +are required when different numeric types are mixed in an expression +or assignment. For instance, <code>int32</code> and <code>int</code> +are not the same type even though they may have the same size on a +particular architecture. + + +<h3 id="String_types">String types</h3> + +<p> +A <i>string type</i> represents the set of string values. +Strings behave like arrays of bytes but are immutable: once created, +it is impossible to change the contents of a string. +The predeclared string type is <code>string</code>. + +<p> +The elements of strings have type <code>byte</code> and may be +accessed using the usual <a href="#Indexes">indexing operations</a>. It is +illegal to take the address of such an element; if +<code>s[i]</code> is the <i>i</i>th byte of a +string, <code>&s[i]</code> is invalid. The length of string +<code>s</code> can be discovered using the built-in function +<code>len</code>. The length is a compile-time constant if <code>s</code> +is a string literal. +</p> + + +<h3 id="Array_types">Array types</h3> + +<p> +An array is a numbered sequence of elements of a single +type, called the element type. +The number of elements is called the length and is never +negative. +</p> + +<pre class="ebnf"> +ArrayType = "[" ArrayLength "]" ElementType . +ArrayLength = Expression . +ElementType = Type . +</pre> + +<p> +The length is part of the array's type and must be a +<a href="#Constant_expressions">constant expression</a> that evaluates to a non-negative +integer value. The length of array <code>a</code> can be discovered +using the built-in function <a href="#Length_and_capacity"><code>len(a)</code></a>. +The elements can be indexed by integer +indices 0 through the <code>len(a)-1</code> (§<a href="#Indexes">Indexes</a>). +Array types are always one-dimensional but may be composed to form +multi-dimensional types. +</p> + +<pre> +[32]byte +[2*N] struct { x, y int32 } +[1000]*float64 +[3][5]int +[2][2][2]float64 // same as [2]([2]([2]float64)) +</pre> + +<h3 id="Slice_types">Slice types</h3> + +<p> +A slice is a reference to a contiguous segment of an array and +contains a numbered sequence of elements from that array. A slice +type denotes the set of all slices of arrays of its element type. +The value of an uninitialized slice is <code>nil</code>. +</p> + +<pre class="ebnf"> +SliceType = "[" "]" ElementType . +</pre> + +<p> +Like arrays, slices are indexable and have a length. The length of a +slice <code>s</code> can be discovered by the built-in function +<a href="#Length_and_capacity"><code>len(s)</code></a>; unlike with arrays it may change during +execution. The elements can be addressed by integer indices 0 +through <code>len(s)-1</code> (§<a href="#Indexes">Indexes</a>). The slice index of a +given element may be less than the index of the same element in the +underlying array. +</p> +<p> +A slice, once initialized, is always associated with an underlying +array that holds its elements. A slice therefore shares storage +with its array and with other slices of the same array; by contrast, +distinct arrays always represent distinct storage. +</p> +<p> +The array underlying a slice may extend past the end of the slice. +The <i>capacity</i> is a measure of that extent: it is the sum of +the length of the slice and the length of the array beyond the slice; +a slice of length up to that capacity can be created by `slicing' a new +one from the original slice (§<a href="#Slices">Slices</a>). +The capacity of a slice <code>a</code> can be discovered using the +built-in function <a href="#Length_and_capacity"><code>cap(a)</code></a>. +</p> + +<p> +A new, initialized slice value for a given element type <code>T</code> is +made using the built-in function +<a href="#Making_slices_maps_and_channels"><code>make</code></a>, +which takes a slice type +and parameters specifying the length and optionally the capacity: +</p> + +<pre> +make([]T, length) +make([]T, length, capacity) +</pre> + +<p> +A call to <code>make</code> allocates a new, hidden array to which the returned +slice value refers. That is, executing +</p> + +<pre> +make([]T, length, capacity) +</pre> + +<p> +produces the same slice as allocating an array and slicing it, so these two examples +result in the same slice: +</p> + +<pre> +make([]int, 50, 100) +new([100]int)[0:50] +</pre> + +<p> +Like arrays, slices are always one-dimensional but may be composed to construct +higher-dimensional objects. +With arrays of arrays, the inner arrays are, by construction, always the same length; +however with slices of slices (or arrays of slices), the lengths may vary dynamically. +Moreover, the inner slices must be allocated individually (with <code>make</code>). +</p> + +<h3 id="Struct_types">Struct types</h3> + +<p> +A struct is a sequence of named elements, called fields, each of which has a +name and a type. Field names may be specified explicitly (IdentifierList) or +implicitly (AnonymousField). +Within a struct, non-<a href="#Blank_identifier">blank</a> field names must +be unique. +</p> + +<pre class="ebnf"> +StructType = "struct" "{" { FieldDecl ";" } "}" . +FieldDecl = (IdentifierList Type | AnonymousField) [ Tag ] . +AnonymousField = [ "*" ] TypeName . +Tag = string_lit . +</pre> + +<pre> +// An empty struct. +struct {} + +// A struct with 6 fields. +struct { + x, y int + u float32 + _ float32 // padding + A *[]int + F func() +} +</pre> + +<p> +A field declared with a type but no explicit field name is an <i>anonymous field</i> +(colloquially called an embedded field). +Such a field type must be specified as +a type name <code>T</code> or as a pointer to a non-interface type name <code>*T</code>, +and <code>T</code> itself may not be +a pointer type. The unqualified type name acts as the field name. +</p> + +<pre> +// A struct with four anonymous fields of type T1, *T2, P.T3 and *P.T4 +struct { + T1 // field name is T1 + *T2 // field name is T2 + P.T3 // field name is T3 + *P.T4 // field name is T4 + x, y int // field names are x and y +} +</pre> + +<p> +The following declaration is illegal because field names must be unique +in a struct type: +</p> + +<pre> +struct { + T // conflicts with anonymous field *T and *P.T + *T // conflicts with anonymous field T and *P.T + *P.T // conflicts with anonymous field T and *T +} +</pre> + +<p> +Fields and methods (§<a href="#Method_declarations">Method declarations</a>) of an anonymous field are +promoted to be ordinary fields and methods of the struct (§<a href="#Selectors">Selectors</a>). +The following rules apply for a struct type named <code>S</code> and +a type named <code>T</code>: +</p> +<ul> + <li>If <code>S</code> contains an anonymous field <code>T</code>, the + <a href="#Method_sets">method set</a> of <code>S</code> includes the + method set of <code>T</code>. + </li> + + <li>If <code>S</code> contains an anonymous field <code>*T</code>, the + method set of <code>S</code> includes the method set of <code>*T</code> + (which itself includes the method set of <code>T</code>). + </li> + + <li>If <code>S</code> contains an anonymous field <code>T</code> or + <code>*T</code>, the method set of <code>*S</code> includes the + method set of <code>*T</code> (which itself includes the method + set of <code>T</code>). + </li> +</ul> +<p> +A field declaration may be followed by an optional string literal <i>tag</i>, +which becomes an attribute for all the fields in the corresponding +field declaration. The tags are made +visible through a <a href="#Package_unsafe">reflection interface</a> +but are otherwise ignored. +</p> + +<pre> +// A struct corresponding to the TimeStamp protocol buffer. +// The tag strings define the protocol buffer field numbers. +struct { + microsec uint64 "field 1" + serverIP6 uint64 "field 2" + process string "field 3" +} +</pre> + +<h3 id="Pointer_types">Pointer types</h3> + +<p> +A pointer type denotes the set of all pointers to variables of a given +type, called the <i>base type</i> of the pointer. +The value of an uninitialized pointer is <code>nil</code>. +</p> + +<pre class="ebnf"> +PointerType = "*" BaseType . +BaseType = Type . +</pre> + +<pre> +*int +*map[string] *chan int +</pre> + +<h3 id="Function_types">Function types</h3> + +<p> +A function type denotes the set of all functions with the same parameter +and result types. The value of an uninitialized variable of function type +is <code>nil</code>. +</p> + +<pre class="ebnf"> +FunctionType = "func" Signature . +Signature = Parameters [ Result ] . +Result = Parameters | Type . +Parameters = "(" [ ParameterList [ "," ] ] ")" . +ParameterList = ParameterDecl { "," ParameterDecl } . +ParameterDecl = [ IdentifierList ] [ "..." ] Type . +</pre> + +<p> +Within a list of parameters or results, the names (IdentifierList) +must either all be present or all be absent. If present, each name +stands for one item (parameter or result) of the specified type; if absent, each +type stands for one item of that type. Parameter and result +lists are always parenthesized except that if there is exactly +one unnamed result it may be written as an unparenthesized type. +</p> + +<p> +The final parameter in a function signature may have +a type prefixed with <code>...</code>. +A function with such a parameter is called <i>variadic</i> and +may be invoked with zero or more arguments for that parameter. +</p> + +<pre> +func() +func(x int) +func() int +func(prefix string, values ...int) +func(a, b int, z float32) bool +func(a, b int, z float32) (bool) +func(a, b int, z float64, opt ...interface{}) (success bool) +func(int, int, float64) (float64, *[]int) +func(n int) func(p *T) +</pre> + + +<h3 id="Interface_types">Interface types</h3> + +<p> +An interface type specifies a <a href="#Method_sets">method set</a> called its <i>interface</i>. +A variable of interface type can store a value of any type with a method set +that is any superset of the interface. Such a type is said to +<i>implement the interface</i>. +The value of an uninitialized variable of interface type is <code>nil</code>. +</p> + +<pre class="ebnf"> +InterfaceType = "interface" "{" { MethodSpec ";" } "}" . +MethodSpec = MethodName Signature | InterfaceTypeName . +MethodName = identifier . +InterfaceTypeName = TypeName . +</pre> + +<p> +As with all method sets, in an interface type, each method must have a unique name. +</p> + +<pre> +// A simple File interface +interface { + Read(b Buffer) bool + Write(b Buffer) bool + Close() +} +</pre> + +<p> +More than one type may implement an interface. +For instance, if two types <code>S1</code> and <code>S2</code> +have the method set +</p> + +<pre> +func (p T) Read(b Buffer) bool { return … } +func (p T) Write(b Buffer) bool { return … } +func (p T) Close() { … } +</pre> + +<p> +(where <code>T</code> stands for either <code>S1</code> or <code>S2</code>) +then the <code>File</code> interface is implemented by both <code>S1</code> and +<code>S2</code>, regardless of what other methods +<code>S1</code> and <code>S2</code> may have or share. +</p> + +<p> +A type implements any interface comprising any subset of its methods +and may therefore implement several distinct interfaces. For +instance, all types implement the <i>empty interface</i>: +</p> + +<pre> +interface{} +</pre> + +<p> +Similarly, consider this interface specification, +which appears within a <a href="#Type_declarations">type declaration</a> +to define an interface called <code>Lock</code>: +</p> + +<pre> +type Lock interface { + Lock() + Unlock() +} +</pre> + +<p> +If <code>S1</code> and <code>S2</code> also implement +</p> + +<pre> +func (p T) Lock() { … } +func (p T) Unlock() { … } +</pre> + +<p> +they implement the <code>Lock</code> interface as well +as the <code>File</code> interface. +</p> +<p> +An interface may contain an interface type name <code>T</code> +in place of a method specification. +The effect is equivalent to enumerating the methods of <code>T</code> explicitly +in the interface. +</p> + +<pre> +type ReadWrite interface { + Read(b Buffer) bool + Write(b Buffer) bool +} + +type File interface { + ReadWrite // same as enumerating the methods in ReadWrite + Lock // same as enumerating the methods in Lock + Close() +} +</pre> + +<h3 id="Map_types">Map types</h3> + +<p> +A map is an unordered group of elements of one type, called the +element type, indexed by a set of unique <i>keys</i> of another type, +called the key type. +The value of an uninitialized map is <code>nil</code>. +</p> + +<pre class="ebnf"> +MapType = "map" "[" KeyType "]" ElementType . +KeyType = Type . +</pre> + +<p> +The comparison operators <code>==</code> and <code>!=</code> +(§<a href="#Comparison_operators">Comparison operators</a>) must be fully defined +for operands of the key type; thus the key type must not be a struct, array or slice. +If the key type is an interface type, these +comparison operators must be defined for the dynamic key values; +failure will cause a <a href="#Run_time_panics">run-time panic</a>. + +</p> + +<pre> +map [string] int +map [*T] struct { x, y float64 } +map [string] interface {} +</pre> + +<p> +The number of map elements is called its length. +For a map <code>m</code>, it can be discovered using the +built-in function <a href="#Length_and_capacity"><code>len(m)</code></a> +and may change during execution. Elements may be added and removed +during execution using special forms of <a href="#Assignments">assignment</a>; +and they may be accessed with <a href="#Indexes">index</a> expressions. +</p> +<p> +A new, empty map value is made using the built-in +function <a href="#Making_slices_maps_and_channels"><code>make</code></a>, +which takes the map type and an optional capacity hint as arguments: +</p> + +<pre> +make(map[string] int) +make(map[string] int, 100) +</pre> + +<p> +The initial capacity does not bound its size: +maps grow to accommodate the number of items +stored in them, with the exception of <code>nil</code> maps. +A <code>nil</code> map is equivalent to an empty map except that no elements +may be added. + +<h3 id="Channel_types">Channel types</h3> + +<p> +A channel provides a mechanism for two concurrently executing functions +to synchronize execution and communicate by passing a value of a +specified element type. +The value of an uninitialized channel is <code>nil</code>. +</p> + +<pre class="ebnf"> +ChannelType = ( "chan" [ "<-" ] | "<-" "chan" ) ElementType . +</pre> + +<p> +The <code><-</code> operator specifies the channel <i>direction</i>, +<i>send</i> or <i>receive</i>. If no direction is given, the channel is +<i>bi-directional</i>. +A channel may be constrained only to send or only to receive by +<a href="#Conversions">conversion</a> or <a href="#Assignments">assignment</a>. +</p> + +<pre> +chan T // can be used to send and receive values of type T +chan<- float64 // can only be used to send float64s +<-chan int // can only be used to receive ints +</pre> + +<p> +The <code><-</code> operator associates with the leftmost <code>chan</code> +possible: +</p> + +<pre> +chan<- chan int // same as chan<- (chan int) +chan<- <-chan int // same as chan<- (<-chan int) +<-chan <-chan int // same as <-chan (<-chan int) +chan (<-chan int) +</pre> + +<p> +A new, initialized channel +value can be made using the built-in function +<a href="#Making_slices_maps_and_channels"><code>make</code></a>, +which takes the channel type and an optional capacity as arguments: +</p> + +<pre> +make(chan int, 100) +</pre> + +<p> +The capacity, in number of elements, sets the size of the buffer in the channel. If the +capacity is greater than zero, the channel is asynchronous: communication operations +succeed without blocking if the buffer is not full (sends) or not empty (receives), +and elements are received in the order they are sent. +If the capacity is zero or absent, the communication succeeds only when both a sender and +receiver are ready. +A <code>nil</code> channel is never ready for communication. +</p> + +<p> +A channel may be closed with the built-in function +<a href="#Close"><code>close</code></a>; the +multi-valued assignment form of the +<a href="#Receive_operator">receive operator</a> +tests whether a channel has been closed. +</p> + +<h2 id="Properties_of_types_and_values">Properties of types and values</h2> + +<h3 id="Type_identity">Type identity</h3> + +<p> +Two types are either <i>identical</i> or <i>different</i>. +</p> + +<p> +Two named types are identical if their type names originate in the same +type <a href="#Declarations_and_scope">declaration</a>. +A named and an unnamed type are always different. Two unnamed types are identical +if the corresponding type literals are identical, that is, if they have the same +literal structure and corresponding components have identical types. In detail: +</p> + +<ul> + <li>Two array types are identical if they have identical element types and + the same array length.</li> + + <li>Two slice types are identical if they have identical element types.</li> + + <li>Two struct types are identical if they have the same sequence of fields, + and if corresponding fields have the same names, and identical types, + and identical tags. + Two anonymous fields are considered to have the same name. Lower-case field + names from different packages are always different.</li> + + <li>Two pointer types are identical if they have identical base types.</li> + + <li>Two function types are identical if they have the same number of parameters + and result values, corresponding parameter and result types are + identical, and either both functions are variadic or neither is. + Parameter and result names are not required to match.</li> + + <li>Two interface types are identical if they have the same set of methods + with the same names and identical function types. Lower-case method names from + different packages are always different. The order of the methods is irrelevant.</li> + + <li>Two map types are identical if they have identical key and value types.</li> + + <li>Two channel types are identical if they have identical value types and + the same direction.</li> +</ul> + +<p> +Given the declarations +</p> + +<pre> +type ( + T0 []string + T1 []string + T2 struct { a, b int } + T3 struct { a, c int } + T4 func(int, float64) *T0 + T5 func(x int, y float64) *[]string +) +</pre> + +<p> +these types are identical: +</p> + +<pre> +T0 and T0 +[]int and []int +struct { a, b *T5 } and struct { a, b *T5 } +func(x int, y float64) *[]string and func(int, float64) (result *[]string) +</pre> + +<p> +<code>T0</code> and <code>T1</code> are different because they are named types +with distinct declarations; <code>func(int, float64) *T0</code> and +<code>func(x int, y float64) *[]string</code> are different because <code>T0</code> +is different from <code>[]string</code>. +</p> + + +<h3 id="Assignability">Assignability</h3> + +<p> +A value <code>x</code> is <i>assignable</i> to a variable of type <code>T</code> +("<code>x</code> is assignable to <code>T</code>") in any of these cases: +</p> + +<ul> +<li> +<code>x</code>'s type is identical to <code>T</code>. +</li> +<li> +<code>x</code>'s type <code>V</code> and <code>T</code> have identical +<a href="#Types">underlying types</a> and at least one of <code>V</code> +or <code>T</code> is not a named type. +</li> +<li> +<code>T</code> is an interface type and +<code>x</code> <a href="#Interface_types">implements</a> <code>T</code>. +</li> +<li> +<code>x</code> is a bidirectional channel value, <code>T</code> is a channel type, +<code>x</code>'s type <code>V</code> and <code>T</code> have identical element types, +and at least one of <code>V</code> or <code>T</code> is not a named type. +</li> +<li> +<code>x</code> is the predeclared identifier <code>nil</code> and <code>T</code> +is a pointer, function, slice, map, channel, or interface type. +</li> +<li> +<code>x</code> is an untyped <a href="#Constants">constant</a> representable +by a value of type <code>T</code>. +</li> +</ul> + +<p> +If <code>T</code> is a struct type with non-<a href="#Exported_identifiers">exported</a> +fields, the assignment must be in the same package in which <code>T</code> is declared, +or <code>x</code> must be the receiver of a method call. +In other words, a struct value can be assigned to a struct variable only if +every field of the struct may be legally assigned individually by the program, +or if the assignment is initializing the receiver of a method of the struct type. +</p> + +<p> +Any value may be assigned to the <a href="#Blank_identifier">blank identifier</a>. +</p> + + +<h2 id="Blocks">Blocks</h2> + +<p> +A <i>block</i> is a sequence of declarations and statements within matching +brace brackets. +</p> + +<pre class="ebnf"> +Block = "{" { Statement ";" } "}" . +</pre> + +<p> +In addition to explicit blocks in the source code, there are implicit blocks: +</p> + +<ol> + <li>The <i>universe block</i> encompasses all Go source text.</li> + + <li>Each <a href="#Packages">package</a> has a <i>package block</i> containing all + Go source text for that package.</li> + + <li>Each file has a <i>file block</i> containing all Go source text + in that file.</li> + + <li>Each <code>if</code>, <code>for</code>, and <code>switch</code> + statement is considered to be in its own implicit block.</li> + + <li>Each clause in a <code>switch</code> or <code>select</code> statement + acts as an implicit block.</li> +</ol> + +<p> +Blocks nest and influence <a href="#Declarations_and_scope">scoping</a>. +</p> + + +<h2 id="Declarations_and_scope">Declarations and scope</h2> + +<p> +A declaration binds a non-<a href="#Blank_identifier">blank</a> +identifier to a constant, type, variable, function, or package. +Every identifier in a program must be declared. +No identifier may be declared twice in the same block, and +no identifier may be declared in both the file and package block. +</p> + +<pre class="ebnf"> +Declaration = ConstDecl | TypeDecl | VarDecl . +TopLevelDecl = Declaration | FunctionDecl | MethodDecl . +</pre> + +<p> +The <i>scope</i> of a declared identifier is the extent of source text in which +the identifier denotes the specified constant, type, variable, function, or package. +</p> + +<p> +Go is lexically scoped using blocks: +</p> + +<ol> + <li>The scope of a predeclared identifier is the universe block.</li> + + <li>The scope of an identifier denoting a constant, type, variable, + or function (but not method) declared at top level (outside any + function) is the package block.</li> + + <li>The scope of an imported package identifier is the file block + of the file containing the import declaration.</li> + + <li>The scope of an identifier denoting a function parameter or + result variable is the function body.</li> + + <li>The scope of a constant or variable identifier declared + inside a function begins at the end of the ConstSpec or VarSpec + (ShortVarDecl for short variable declarations) + and ends at the end of the innermost containing block.</li> + + <li>The scope of a type identifier declared inside a function + begins at the identifier in the TypeSpec + and ends at the end of the innermost containing block.</li> +</ol> + +<p> +An identifier declared in a block may be redeclared in an inner block. +While the identifier of the inner declaration is in scope, it denotes +the entity declared by the inner declaration. +</p> + +<p> +The <a href="#Package_clause">package clause</a> is not a declaration; the package name +does not appear in any scope. Its purpose is to identify the files belonging +to the same <a href="#Packages">package</a> and to specify the default package name for import +declarations. +</p> + + +<h3 id="Label_scopes">Label scopes</h3> + +<p> +Labels are declared by <a href="#Labeled_statements">labeled statements</a> and are +used in the <code>break</code>, <code>continue</code>, and <code>goto</code> +statements (§<a href="#Break_statements">Break statements</a>, §<a href="#Continue_statements">Continue statements</a>, §<a href="#Goto_statements">Goto statements</a>). +It is illegal to define a label that is never used. +In contrast to other identifiers, labels are not block scoped and do +not conflict with identifiers that are not labels. The scope of a label +is the body of the function in which it is declared and excludes +the body of any nested function. +</p> + + +<h3 id="Predeclared_identifiers">Predeclared identifiers</h3> + +<p> +The following identifiers are implicitly declared in the universe block: +</p> +<pre class="grammar"> +Basic types: + bool byte complex64 complex128 float32 float64 + int8 int16 int32 int64 string uint8 uint16 uint32 uint64 + +Architecture-specific convenience types: + int uint uintptr + +Constants: + true false iota + +Zero value: + nil + +Functions: + append cap close complex copy imag len + make new panic print println real recover +</pre> + + +<h3 id="Exported_identifiers">Exported identifiers</h3> + +<p> +An identifier may be <i>exported</i> to permit access to it from another package +using a <a href="#Qualified_identifiers">qualified identifier</a>. An identifier +is exported if both: +</p> +<ol> + <li>the first character of the identifier's name is a Unicode upper case letter (Unicode class "Lu"); and</li> + <li>the identifier is declared in the <a href="#Blocks">package block</a> or denotes a field or method of a type + declared in that block.</li> +</ol> +<p> +All other identifiers are not exported. +</p> + + +<h3 id="Blank_identifier">Blank identifier</h3> + +<p> +The <i>blank identifier</i>, represented by the underscore character <code>_</code>, may be used in a declaration like +any other identifier but the declaration does not introduce a new binding. +</p> + + +<h3 id="Constant_declarations">Constant declarations</h3> + +<p> +A constant declaration binds a list of identifiers (the names of +the constants) to the values of a list of <a href="#Constant_expressions">constant expressions</a>. +The number of identifiers must be equal +to the number of expressions, and the <i>n</i>th identifier on +the left is bound to the value of the <i>n</i>th expression on the +right. +</p> + +<pre class="ebnf"> +ConstDecl = "const" ( ConstSpec | "(" { ConstSpec ";" } ")" ) . +ConstSpec = IdentifierList [ [ Type ] "=" ExpressionList ] . + +IdentifierList = identifier { "," identifier } . +ExpressionList = Expression { "," Expression } . +</pre> + +<p> +If the type is present, all constants take the type specified, and +the expressions must be <a href="#Assignability">assignable</a> to that type. +If the type is omitted, the constants take the +individual types of the corresponding expressions. +If the expression values are untyped <a href="#Constants">constants</a>, +the declared constants remain untyped and the constant identifiers +denote the constant values. For instance, if the expression is a +floating-point literal, the constant identifier denotes a floating-point +constant, even if the literal's fractional part is zero. +</p> + +<pre> +const Pi float64 = 3.14159265358979323846 +const zero = 0.0 // untyped floating-point constant +const ( + size int64 = 1024 + eof = -1 // untyped integer constant +) +const a, b, c = 3, 4, "foo" // a = 3, b = 4, c = "foo", untyped integer and string constants +const u, v float32 = 0, 3 // u = 0.0, v = 3.0 +</pre> + +<p> +Within a parenthesized <code>const</code> declaration list the +expression list may be omitted from any but the first declaration. +Such an empty list is equivalent to the textual substitution of the +first preceding non-empty expression list and its type if any. +Omitting the list of expressions is therefore equivalent to +repeating the previous list. The number of identifiers must be equal +to the number of expressions in the previous list. +Together with the <a href="#Iota"><code>iota</code> constant generator</a> +this mechanism permits light-weight declaration of sequential values: +</p> + +<pre> +const ( + Sunday = iota + Monday + Tuesday + Wednesday + Thursday + Friday + Partyday + numberOfDays // this constant is not exported +) +</pre> + + +<h3 id="Iota">Iota</h3> + +<p> +Within a <a href="#Constant_declarations">constant declaration</a>, the predeclared identifier +<code>iota</code> represents successive untyped integer <a href="#Constants"> +constants</a>. It is reset to 0 whenever the reserved word <code>const</code> +appears in the source and increments after each <a href="#ConstSpec">ConstSpec</a>. +It can be used to construct a set of related constants: +</p> + +<pre> +const ( // iota is reset to 0 + c0 = iota // c0 == 0 + c1 = iota // c1 == 1 + c2 = iota // c2 == 2 +) + +const ( + a = 1 << iota // a == 1 (iota has been reset) + b = 1 << iota // b == 2 + c = 1 << iota // c == 4 +) + +const ( + u = iota * 42 // u == 0 (untyped integer constant) + v float64 = iota * 42 // v == 42.0 (float64 constant) + w = iota * 42 // w == 84 (untyped integer constant) +) + +const x = iota // x == 0 (iota has been reset) +const y = iota // y == 0 (iota has been reset) +</pre> + +<p> +Within an ExpressionList, the value of each <code>iota</code> is the same because +it is only incremented after each ConstSpec: +</p> + +<pre> +const ( + bit0, mask0 = 1 << iota, 1 << iota - 1 // bit0 == 1, mask0 == 0 + bit1, mask1 // bit1 == 2, mask1 == 1 + _, _ // skips iota == 2 + bit3, mask3 // bit3 == 8, mask3 == 7 +) +</pre> + +<p> +This last example exploits the implicit repetition of the +last non-empty expression list. +</p> + + +<h3 id="Type_declarations">Type declarations</h3> + +<p> +A type declaration binds an identifier, the <i>type name</i>, to a new type +that has the same <a href="#Types">underlying type</a> as +an existing type. The new type is <a href="#Type_identity">different</a> from +the existing type. +</p> + +<pre class="ebnf"> +TypeDecl = "type" ( TypeSpec | "(" { TypeSpec ";" } ")" ) . +TypeSpec = identifier Type . +</pre> + +<pre> +type IntArray [16]int + +type ( + Point struct { x, y float64 } + Polar Point +) + +type TreeNode struct { + left, right *TreeNode + value *Comparable +} + +type Cipher interface { + BlockSize() int + Encrypt(src, dst []byte) + Decrypt(src, dst []byte) +} +</pre> + +<p> +The declared type does not inherit any <a href="#Method_declarations">methods</a> +bound to the existing type, but the <a href="#Method_sets">method set</a> +of an interface type or of elements of a composite type remains unchanged: +</p> + +<pre> +// A Mutex is a data type with two methods, Lock and Unlock. +type Mutex struct { /* Mutex fields */ } +func (m *Mutex) Lock() { /* Lock implementation */ } +func (m *Mutex) Unlock() { /* Unlock implementation */ } + +// NewMutex has the same composition as Mutex but its method set is empty. +type NewMutex Mutex + +// The method set of the <a href="#Pointer_types">base type</a> of PtrMutex remains unchanged, +// but the method set of PtrMutex is empty. +type PtrMutex *Mutex + +// The method set of *PrintableMutex contains the methods +// Lock and Unlock bound to its anonymous field Mutex. +type PrintableMutex struct { + Mutex +} + +// MyCipher is an interface type that has the same method set as Cipher. +type MyCipher Cipher +</pre> + +<p> +A type declaration may be used to define a different boolean, numeric, or string +type and attach methods to it: +</p> + +<pre> +type TimeZone int + +const ( + EST TimeZone = -(5 + iota) + CST + MST + PST +) + +func (tz TimeZone) String() string { + return fmt.Sprintf("GMT+%dh", tz) +} +</pre> + + +<h3 id="Variable_declarations">Variable declarations</h3> + +<p> +A variable declaration creates a variable, binds an identifier to it and +gives it a type and optionally an initial value. +</p> +<pre class="ebnf"> +VarDecl = "var" ( VarSpec | "(" { VarSpec ";" } ")" ) . +VarSpec = IdentifierList ( Type [ "=" ExpressionList ] | "=" ExpressionList ) . +</pre> + +<pre> +var i int +var U, V, W float64 +var k = 0 +var x, y float32 = -1, -2 +var ( + i int + u, v, s = 2.0, 3.0, "bar" +) +var re, im = complexSqrt(-1) +var _, found = entries[name] // map lookup; only interested in "found" +</pre> + +<p> +If a list of expressions is given, the variables are initialized +by assigning the expressions to the variables (§<a href="#Assignments">Assignments</a>) +in order; all expressions must be consumed and all variables initialized from them. +Otherwise, each variable is initialized to its <a href="#The_zero_value">zero value</a>. +</p> + +<p> +If the type is present, each variable is given that type. +Otherwise, the types are deduced from the assignment +of the expression list. +</p> + +<p> +If the type is absent and the corresponding expression evaluates to an +untyped <a href="#Constants">constant</a>, the type of the declared variable +is <code>bool</code>, <code>int</code>, <code>float64</code>, or <code>string</code> +respectively, depending on whether the value is a boolean, integer, +floating-point, or string constant: +</p> + +<pre> +var b = true // t has type bool +var i = 0 // i has type int +var f = 3.0 // f has type float64 +var s = "OMDB" // s has type string +</pre> + +<h3 id="Short_variable_declarations">Short variable declarations</h3> + +<p> +A <i>short variable declaration</i> uses the syntax: +</p> + +<pre class="ebnf"> +ShortVarDecl = IdentifierList ":=" ExpressionList . +</pre> + +<p> +It is a shorthand for a regular variable declaration with +initializer expressions but no types: +</p> + +<pre class="grammar"> +"var" IdentifierList = ExpressionList . +</pre> + +<pre> +i, j := 0, 10 +f := func() int { return 7 } +ch := make(chan int) +r, w := os.Pipe(fd) // os.Pipe() returns two values +_, y, _ := coord(p) // coord() returns three values; only interested in y coordinate +</pre> + +<p> +Unlike regular variable declarations, a short variable declaration may redeclare variables provided they +were originally declared in the same block with the same type, and at +least one of the non-<a href="#Blank_identifier">blank</a> variables is new. As a consequence, redeclaration +can only appear in a multi-variable short declaration. +Redeclaration does not introduce a new +variable; it just assigns a new value to the original. +</p> + +<pre> +field1, offset := nextField(str, 0) +field2, offset := nextField(str, offset) // redeclares offset +</pre> + +<p> +Short variable declarations may appear only inside functions. +In some contexts such as the initializers for <code>if</code>, +<code>for</code>, or <code>switch</code> statements, +they can be used to declare local temporary variables (§<a href="#Statements">Statements</a>). +</p> + +<h3 id="Function_declarations">Function declarations</h3> + +<p> +A function declaration binds an identifier to a function (§<a href="#Function_types">Function types</a>). +</p> + +<pre class="ebnf"> +FunctionDecl = "func" identifier Signature [ Body ] . +Body = Block . +</pre> + +<p> +A function declaration may omit the body. Such a declaration provides the +signature for a function implemented outside Go, such as an assembly routine. +</p> + +<pre> +func min(x int, y int) int { + if x < y { + return x + } + return y +} + +func flushICache(begin, end uintptr) // implemented externally +</pre> + +<h3 id="Method_declarations">Method declarations</h3> + +<p> +A method is a function with a <i>receiver</i>. +A method declaration binds an identifier to a method. +</p> +<pre class="ebnf"> +MethodDecl = "func" Receiver MethodName Signature [ Body ] . +Receiver = "(" [ identifier ] [ "*" ] BaseTypeName ")" . +BaseTypeName = identifier . +</pre> + +<p> +The receiver type must be of the form <code>T</code> or <code>*T</code> where +<code>T</code> is a type name. <code>T</code> is called the +<i>receiver base type</i> or just <i>base type</i>. +The base type must not be a pointer or interface type and must be +declared in the same package as the method. +The method is said to be <i>bound</i> to the base type +and is visible only within selectors for that type +(§<a href="#Type_declarations">Type declarations</a>, §<a href="#Selectors">Selectors</a>). +</p> + +<p> +Given type <code>Point</code>, the declarations +</p> + +<pre> +func (p *Point) Length() float64 { + return math.Sqrt(p.x * p.x + p.y * p.y) +} + +func (p *Point) Scale(factor float64) { + p.x *= factor + p.y *= factor +} +</pre> + +<p> +bind the methods <code>Length</code> and <code>Scale</code>, +with receiver type <code>*Point</code>, +to the base type <code>Point</code>. +</p> + +<p> +If the receiver's value is not referenced inside the body of the method, +its identifier may be omitted in the declaration. The same applies in +general to parameters of functions and methods. +</p> + +<p> +The type of a method is the type of a function with the receiver as first +argument. For instance, the method <code>Scale</code> has type +</p> + +<pre> +func(p *Point, factor float64) +</pre> + +<p> +However, a function declared this way is not a method. +</p> + + +<h2 id="Expressions">Expressions</h2> + +<p> +An expression specifies the computation of a value by applying +operators and functions to operands. +</p> + +<h3 id="Operands">Operands</h3> + +<p> +Operands denote the elementary values in an expression. +</p> + +<pre class="ebnf"> +Operand = Literal | QualifiedIdent | MethodExpr | "(" Expression ")" . +Literal = BasicLit | CompositeLit | FunctionLit . +BasicLit = int_lit | float_lit | imaginary_lit | char_lit | string_lit . +</pre> + + +<h3 id="Qualified_identifiers">Qualified identifiers</h3> + +<p> +A qualified identifier is a non-<a href="#Blank_identifier">blank</a> identifier qualified by a package name prefix. +</p> + +<pre class="ebnf"> +QualifiedIdent = [ PackageName "." ] identifier . +</pre> + +<p> +A qualified identifier accesses an identifier in a separate package. +The identifier must be <a href="#Exported_identifiers">exported</a> by that +package, which means that it must begin with a Unicode upper case letter. +</p> + +<pre> +math.Sin +</pre> + +<!-- +<p> +<span class="alert">TODO: Unify this section with Selectors - it's the same syntax.</span> +</p> +--> + +<h3 id="Composite_literals">Composite literals</h3> + +<p> +Composite literals construct values for structs, arrays, slices, and maps +and create a new value each time they are evaluated. +They consist of the type of the value +followed by a brace-bound list of composite elements. An element may be +a single expression or a key-value pair. +</p> + +<pre class="ebnf"> +CompositeLit = LiteralType LiteralValue . +LiteralType = StructType | ArrayType | "[" "..." "]" ElementType | + SliceType | MapType | TypeName . +LiteralValue = "{" [ ElementList [ "," ] ] "}" . +ElementList = Element { "," Element } . +Element = [ Key ":" ] Value . +Key = FieldName | ElementIndex . +FieldName = identifier . +ElementIndex = Expression . +Value = Expression | LiteralValue . +</pre> + +<p> +The LiteralType must be a struct, array, slice, or map type +(the grammar enforces this constraint except when the type is given +as a TypeName). +The types of the expressions must be <a href="#Assignability">assignable</a> +to the respective field, element, and key types of the LiteralType; +there is no additional conversion. +The key is interpreted as a field name for struct literals, +an index expression for array and slice literals, and a key for map literals. +For map literals, all elements must have a key. It is an error +to specify multiple elements with the same field name or +constant key value. +</p> + +<p> +For struct literals the following rules apply: +</p> +<ul> + <li>A key must be a field name declared in the LiteralType. + </li> + <li>A literal that does not contain any keys must + list an element for each struct field in the + order in which the fields are declared. + </li> + <li>If any element has a key, every element must have a key. + </li> + <li>A literal that contains keys does not need to + have an element for each struct field. Omitted fields + get the zero value for that field. + </li> + <li>A literal may omit the element list; such a literal evaluates + to the zero value for its type. + </li> + <li>It is an error to specify an element for a non-exported + field of a struct belonging to a different package. + </li> +</ul> + +<p> +Given the declarations +</p> +<pre> +type Point3D struct { x, y, z float64 } +type Line struct { p, q Point3D } +</pre> + +<p> +one may write +</p> + +<pre> +origin := Point3D{} // zero value for Point3D +line := Line{origin, Point3D{y: -4, z: 12.3}} // zero value for line.q.x +</pre> + +<p> +For array and slice literals the following rules apply: +</p> +<ul> + <li>Each element has an associated integer index marking + its position in the array. + </li> + <li>An element with a key uses the key as its index; the + key must be a constant integer expression. + </li> + <li>An element without a key uses the previous element's index plus one. + If the first element has no key, its index is zero. + </li> +</ul> + +<p> +Taking the address of a composite literal (§<a href="#Address_operators">Address operators</a>) +generates a pointer to a unique instance of the literal's value. +</p> +<pre> +var pointer *Point3D = &Point3D{y: 1000} +</pre> + +<p> +The length of an array literal is the length specified in the LiteralType. +If fewer elements than the length are provided in the literal, the missing +elements are set to the zero value for the array element type. +It is an error to provide elements with index values outside the index range +of the array. The notation <code>...</code> specifies an array length equal +to the maximum element index plus one. +</p> + +<pre> +buffer := [10]string{} // len(buffer) == 10 +intSet := [6]int{1, 2, 3, 5} // len(intSet) == 6 +days := [...]string{"Sat", "Sun"} // len(days) == 2 +</pre> + +<p> +A slice literal describes the entire underlying array literal. +Thus, the length and capacity of a slice literal are the maximum +element index plus one. A slice literal has the form +</p> + +<pre> +[]T{x1, x2, … xn} +</pre> + +<p> +and is a shortcut for a slice operation applied to an array literal: +</p> + +<pre> +[n]T{x1, x2, … xn}[0 : n] +</pre> + +<p> +Within a composite literal of array, slice, or map type <code>T</code>, +elements that are themselves composite literals may elide the respective +literal type if it is identical to the element type of <code>T</code>. +</p> + +<pre> +[...]Point{{1.5, -3.5}, {0, 0}} // same as [...]Point{Point{1.5, -3.5}, Point{0, 0}} +[][]int{{1, 2, 3}, {4, 5}} // same as [][]int{[]int{1, 2, 3}, []int{4, 5}} +</pre> + +<p> +A parsing ambiguity arises when a composite literal using the +TypeName form of the LiteralType appears between the +<a href="#Keywords">keyword</a> and the opening brace of the block of an +"if", "for", or "switch" statement, because the braces surrounding +the expressions in the literal are confused with those introducing +the block of statements. To resolve the ambiguity in this rare case, +the composite literal must appear within +parentheses. +</p> + +<pre> +if x == (T{a,b,c}[i]) { … } +if (x == T{a,b,c}[i]) { … } +</pre> + +<p> +Examples of valid array, slice, and map literals: +</p> + +<pre> +// list of prime numbers +primes := []int{2, 3, 5, 7, 9, 11, 13, 17, 19, 991} + +// vowels[ch] is true if ch is a vowel +vowels := [128]bool{'a': true, 'e': true, 'i': true, 'o': true, 'u': true, 'y': true} + +// the array [10]float32{-1, 0, 0, 0, -0.1, -0.1, 0, 0, 0, -1} +filter := [10]float32{-1, 4: -0.1, -0.1, 9: -1} + +// frequencies in Hz for equal-tempered scale (A4 = 440Hz) +noteFrequency := map[string]float32{ + "C0": 16.35, "D0": 18.35, "E0": 20.60, "F0": 21.83, + "G0": 24.50, "A0": 27.50, "B0": 30.87, +} +</pre> + + +<h3 id="Function_literals">Function literals</h3> + +<p> +A function literal represents an anonymous function. +It consists of a specification of the function type and a function body. +</p> + +<pre class="ebnf"> +FunctionLit = FunctionType Body . +</pre> + +<pre> +func(a, b int, z float64) bool { return a*b < int(z) } +</pre> + +<p> +A function literal can be assigned to a variable or invoked directly. +</p> + +<pre> +f := func(x, y int) int { return x + y } +func(ch chan int) { ch <- ACK } (reply_chan) +</pre> + +<p> +Function literals are <i>closures</i>: they may refer to variables +defined in a surrounding function. Those variables are then shared between +the surrounding function and the function literal, and they survive as long +as they are accessible. +</p> + + +<h3 id="Primary_expressions">Primary expressions</h3> + +<p> +Primary expressions are the operands for unary and binary expressions. +</p> + +<pre class="ebnf"> +PrimaryExpr = + Operand | + Conversion | + BuiltinCall | + PrimaryExpr Selector | + PrimaryExpr Index | + PrimaryExpr Slice | + PrimaryExpr TypeAssertion | + PrimaryExpr Call . + +Selector = "." identifier . +Index = "[" Expression "]" . +Slice = "[" [ Expression ] ":" [ Expression ] "]" . +TypeAssertion = "." "(" Type ")" . +Call = "(" [ ArgumentList [ "," ] ] ")" . +ArgumentList = ExpressionList [ "..." ] . +</pre> + + +<pre> +x +2 +(s + ".txt") +f(3.1415, true) +Point{1, 2} +m["foo"] +s[i : j + 1] +obj.color +math.Sin +f.p[i].x() +</pre> + + +<h3 id="Selectors">Selectors</h3> + +<p> +A primary expression of the form +</p> + +<pre> +x.f +</pre> + +<p> +denotes the field or method <code>f</code> of the value denoted by <code>x</code> +(or sometimes <code>*x</code>; see below). The identifier <code>f</code> +is called the (field or method) +<i>selector</i>; it must not be the <a href="#Blank_identifier">blank identifier</a>. +The type of the expression is the type of <code>f</code>. +</p> +<p> +A selector <code>f</code> may denote a field or method <code>f</code> of +a type <code>T</code>, or it may refer +to a field or method <code>f</code> of a nested anonymous field of +<code>T</code>. +The number of anonymous fields traversed +to reach <code>f</code> is called its <i>depth</i> in <code>T</code>. +The depth of a field or method <code>f</code> +declared in <code>T</code> is zero. +The depth of a field or method <code>f</code> declared in +an anonymous field <code>A</code> in <code>T</code> is the +depth of <code>f</code> in <code>A</code> plus one. +</p> +<p> +The following rules apply to selectors: +</p> +<ol> +<li> +For a value <code>x</code> of type <code>T</code> or <code>*T</code> +where <code>T</code> is not an interface type, +<code>x.f</code> denotes the field or method at the shallowest depth +in <code>T</code> where there +is such an <code>f</code>. +If there is not exactly one <code>f</code> with shallowest depth, the selector +expression is illegal. +</li> +<li> +For a variable <code>x</code> of type <code>I</code> +where <code>I</code> is an interface type, +<code>x.f</code> denotes the actual method with name <code>f</code> of the value assigned +to <code>x</code> if there is such a method. +If no value or <code>nil</code> was assigned to <code>x</code>, <code>x.f</code> is illegal. +</li> +<li> +In all other cases, <code>x.f</code> is illegal. +</li> +</ol> +<p> +Selectors automatically dereference pointers to structs. +If <code>x</code> is a pointer to a struct, <code>x.y</code> +is shorthand for <code>(*x).y</code>; if the field <code>y</code> +is also a pointer to a struct, <code>x.y.z</code> is shorthand +for <code>(*(*x).y).z</code>, and so on. +If <code>x</code> contains an anonymous field of type <code>*A</code>, +where <code>A</code> is also a struct type, +<code>x.f</code> is a shortcut for <code>(*x.A).f</code>. +</p> +<p> +For example, given the declarations: +</p> + +<pre> +type T0 struct { + x int +} + +func (recv *T0) M0() + +type T1 struct { + y int +} + +func (recv T1) M1() + +type T2 struct { + z int + T1 + *T0 +} + +func (recv *T2) M2() + +var p *T2 // with p != nil and p.T1 != nil +</pre> + +<p> +one may write: +</p> + +<pre> +p.z // (*p).z +p.y // ((*p).T1).y +p.x // (*(*p).T0).x + +p.M2 // (*p).M2 +p.M1 // ((*p).T1).M1 +p.M0 // ((*p).T0).M0 +</pre> + + +<!-- +<span class="alert"> +TODO: Specify what happens to receivers. +</span> +--> + + +<h3 id="Indexes">Indexes</h3> + +<p> +A primary expression of the form +</p> + +<pre> +a[x] +</pre> + +<p> +denotes the element of the array, slice, string or map <code>a</code> indexed by <code>x</code>. +The value <code>x</code> is called the +<i>index</i> or <i>map key</i>, respectively. The following +rules apply: +</p> + +<p> +For <code>a</code> of type <code>A</code> or <code>*A</code> +where <code>A</code> is an <a href="#Array_types">array type</a>, +or for <code>a</code> of type <code>S</code> where <code>S</code> is a <a href="#Slice_types">slice type</a>: +</p> +<ul> + <li><code>x</code> must be an integer value and <code>0 <= x < len(a)</code></li> + <li><code>a[x]</code> is the array element at index <code>x</code> and the type of + <code>a[x]</code> is the element type of <code>A</code></li> + <li>if <code>a</code> is <code>nil</code> or if the index <code>x</code> is out of range, + a <a href="#Run_time_panics">run-time panic</a> occurs</li> +</ul> + +<p> +For <code>a</code> of type <code>T</code> +where <code>T</code> is a <a href="#String_types">string type</a>: +</p> +<ul> + <li><code>x</code> must be an integer value and <code>0 <= x < len(a)</code></li> + <li><code>a[x]</code> is the byte at index <code>x</code> and the type of + <code>a[x]</code> is <code>byte</code></li> + <li><code>a[x]</code> may not be assigned to</li> + <li>if the index <code>x</code> is out of range, + a <a href="#Run_time_panics">run-time panic</a> occurs</li> +</ul> + +<p> +For <code>a</code> of type <code>M</code> +where <code>M</code> is a <a href="#Map_types">map type</a>: +</p> +<ul> + <li><code>x</code>'s type must be + <a href="#Assignability">assignable</a> + to the key type of <code>M</code></li> + <li>if the map contains an entry with key <code>x</code>, + <code>a[x]</code> is the map value with key <code>x</code> + and the type of <code>a[x]</code> is the value type of <code>M</code></li> + <li>if the map is <code>nil</code> or does not contain such an entry, + <code>a[x]</code> is the <a href="#The_zero_value">zero value</a> + for the value type of <code>M</code></li> +</ul> + +<p> +Otherwise <code>a[x]</code> is illegal. +</p> + +<p> +An index expression on a map <code>a</code> of type <code>map[K]V</code> +may be used in an assignment or initialization of the special form +</p> + +<pre> +v, ok = a[x] +v, ok := a[x] +var v, ok = a[x] +</pre> + +<p> +where the result of the index expression is a pair of values with types +<code>(V, bool)</code>. In this form, the value of <code>ok</code> is +<code>true</code> if the key <code>x</code> is present in the map, and +<code>false</code> otherwise. The value of <code>v</code> is the value +<code>a[x]</code> as in the single-result form. +</p> + +<p> +Similarly, if an assignment to a map element has the special form +</p> + +<pre> +a[x] = v, ok +</pre> + +<p> +and boolean <code>ok</code> has the value <code>false</code>, +the entry for key <code>x</code> is deleted from the map; if +<code>ok</code> is <code>true</code>, the construct acts like +a regular assignment to an element of the map. +</p> + +<p> +Assigning to an element of a <code>nil</code> map causes a +<a href="#Run_time_panics">run-time panic</a>. +</p> + + +<h3 id="Slices">Slices</h3> + +<p> +For a string, array, or slice <code>a</code>, the primary expression +</p> + +<pre> +a[low : high] +</pre> + +<p> +constructs a substring or slice. The index expressions <code>low</code> and +<code>high</code> select which elements appear in the result. The result has +indexes starting at 0 and length equal to +<code>high</code> - <code>low</code>. +After slicing the array <code>a</code> +</p> + +<pre> +a := [5]int{1, 2, 3, 4, 5} +s := a[1:4] +</pre> + +<p> +the slice <code>s</code> has type <code>[]int</code>, length 3, capacity 4, and elements +</p> + +<pre> +s[0] == 2 +s[1] == 3 +s[2] == 4 +</pre> + +<p> +For convenience, any of the index expressions may be omitted. A missing <code>low</code> +index defaults to zero; a missing <code>high</code> index defaults to the length of the +sliced operand: +</p> + +<pre> +a[2:] // same a[2 : len(a)] +a[:3] // same as a[0 : 3] +a[:] // same as a[0 : len(a)] +</pre> + +<p> +For arrays or strings, the indexes <code>low</code> and <code>high</code> must +satisfy 0 <= <code>low</code> <= <code>high</code> <= length; for +slices, the upper bound is the capacity rather than the length. +</p> + +<p> +If the sliced operand is a string or slice, the result of the slice operation +is a string or slice of the same type. +If the sliced operand is an array, it must be <a href="#Address_operators">addressable</a> +and the result of the slice operation is a slice with the same element type as the array. +</p> + + +<h3 id="Type_assertions">Type assertions</h3> + +<p> +For an expression <code>x</code> of <a href="#Interface_types">interface type</a> +and a type <code>T</code>, the primary expression +</p> + +<pre> +x.(T) +</pre> + +<p> +asserts that <code>x</code> is not <code>nil</code> +and that the value stored in <code>x</code> is of type <code>T</code>. +The notation <code>x.(T)</code> is called a <i>type assertion</i>. +</p> +<p> +More precisely, if <code>T</code> is not an interface type, <code>x.(T)</code> asserts +that the dynamic type of <code>x</code> is <a href="#Type_identity">identical</a> +to the type <code>T</code>. +If <code>T</code> is an interface type, <code>x.(T)</code> asserts that the dynamic type +of <code>x</code> implements the interface <code>T</code> (§<a href="#Interface_types">Interface types</a>). +</p> +<p> +If the type assertion holds, the value of the expression is the value +stored in <code>x</code> and its type is <code>T</code>. If the type assertion is false, +a <a href="#Run_time_panics">run-time panic</a> occurs. +In other words, even though the dynamic type of <code>x</code> +is known only at run-time, the type of <code>x.(T)</code> is +known to be <code>T</code> in a correct program. +</p> +<p> +If a type assertion is used in an assignment or initialization of the form +</p> + +<pre> +v, ok = x.(T) +v, ok := x.(T) +var v, ok = x.(T) +</pre> + +<p> +the result of the assertion is a pair of values with types <code>(T, bool)</code>. +If the assertion holds, the expression returns the pair <code>(x.(T), true)</code>; +otherwise, the expression returns <code>(Z, false)</code> where <code>Z</code> +is the <a href="#The_zero_value">zero value</a> for type <code>T</code>. +No run-time panic occurs in this case. +The type assertion in this construct thus acts like a function call +returning a value and a boolean indicating success. (§<a href="#Assignments">Assignments</a>) +</p> + + +<h3 id="Calls">Calls</h3> + +<p> +Given an expression <code>f</code> of function type +<code>F</code>, +</p> + +<pre> +f(a1, a2, … an) +</pre> + +<p> +calls <code>f</code> with arguments <code>a1, a2, … an</code>. +Except for one special case, arguments must be single-valued expressions +<a href="#Assignability">assignable</a> to the parameter types of +<code>F</code> and are evaluated before the function is called. +The type of the expression is the result type +of <code>F</code>. +A method invocation is similar but the method itself +is specified as a selector upon a value of the receiver type for +the method. +</p> + +<pre> +math.Atan2(x, y) // function call +var pt *Point +pt.Scale(3.5) // method call with receiver pt +</pre> + +<p> +As a special case, if the return parameters of a function or method +<code>g</code> are equal in number and individually +assignable to the parameters of another function or method +<code>f</code>, then the call <code>f(g(<i>parameters_of_g</i>))</code> +will invoke <code>f</code> after binding the return values of +<code>g</code> to the parameters of <code>f</code> in order. The call +of <code>f</code> must contain no parameters other than the call of <code>g</code>. +If <code>f</code> has a final <code>...</code> parameter, it is +assigned the return values of <code>g</code> that remain after +assignment of regular parameters. +</p> + +<pre> +func Split(s string, pos int) (string, string) { + return s[0:pos], s[pos:] +} + +func Join(s, t string) string { + return s + t +} + +if Join(Split(value, len(value)/2)) != value { + log.Panic("test fails") +} +</pre> + +<p> +A method call <code>x.m()</code> is valid if the <a href="#Method_sets">method set</a> +of (the type of) <code>x</code> contains <code>m</code> and the +argument list can be assigned to the parameter list of <code>m</code>. +If <code>x</code> is <a href="#Address_operators">addressable</a> and <code>&x</code>'s method +set contains <code>m</code>, <code>x.m()</code> is shorthand +for <code>(&x).m()</code>: +</p> + +<pre> +var p Point +p.Scale(3.5) +</pre> + +<p> +There is no distinct method type and there are no method literals. +</p> + +<h3 id="Passing_arguments_to_..._parameters">Passing arguments to <code>...</code> parameters</h3> + +<p> +If <code>f</code> is variadic with final parameter type <code>...T</code>, +then within the function the argument is equivalent to a parameter of type +<code>[]T</code>. At each call of <code>f</code>, the argument +passed to the final parameter is +a new slice of type <code>[]T</code> whose successive elements are +the actual arguments, which all must be <a href="#Assignability">assignable</a> +to the type <code>T</code>. The length of the slice is therefore the number of +arguments bound to the final parameter and may differ for each call site. +</p> + +<p> +Given the function and call +</p> +<pre> +func Greeting(prefix string, who ...string) +Greeting("hello:", "Joe", "Anna", "Eileen") +</pre> + +<p> +within <code>Greeting</code>, <code>who</code> will have the value +<code>[]string{"Joe", "Anna", "Eileen"}</code> +</p> + +<p> +If the final argument is assignable to a slice type <code>[]T</code>, it may be +passed unchanged as the value for a <code>...T</code> parameter if the argument +is followed by <code>...</code>. In this case no new slice is created. +</p> + +<p> +Given the slice <code>s</code> and call +</p> + +<pre> +s := []string{"James", "Jasmine"} +Greeting("goodbye:", s...) +</pre> + +<p> +within <code>Greeting</code>, <code>who</code> will have the same value as <code>s</code> +with the same underlying array. +</p> + + +<h3 id="Operators">Operators</h3> + +<p> +Operators combine operands into expressions. +</p> + +<pre class="ebnf"> +Expression = UnaryExpr | Expression binary_op UnaryExpr . +UnaryExpr = PrimaryExpr | unary_op UnaryExpr . + +binary_op = "||" | "&&" | rel_op | add_op | mul_op . +rel_op = "==" | "!=" | "<" | "<=" | ">" | ">=" . +add_op = "+" | "-" | "|" | "^" . +mul_op = "*" | "/" | "%" | "<<" | ">>" | "&" | "&^" . + +unary_op = "+" | "-" | "!" | "^" | "*" | "&" | "<-" . +</pre> + +<p> +Comparisons are discussed <a href="#Comparison_operators">elsewhere</a>. +For other binary operators, the operand types must be <a href="#Type_identity">identical</a> +unless the operation involves shifts or untyped <a href="#Constants">constants</a>. +For operations involving constants only, see the section on +<a href="#Constant_expressions">constant expressions</a>. +</p> + +<p> +Except for shift operations, if one operand is an untyped <a href="#Constants">constant</a> +and the other operand is not, the constant is <a href="#Conversions">converted</a> +to the type of the other operand. +</p> + +<p> +The right operand in a shift expression must have unsigned integer type +or be an untyped constant that can be converted to unsigned integer type. +If the left operand of a non-constant shift expression is an untyped constant, +the type of the constant is what it would be if the shift expression were +replaced by its left operand alone; the type is <code>int</code> if it cannot +be determined from the context (for instance, if the shift expression is an +operand in a comparison against an untyped constant). +</p> + +<pre> +var s uint = 33 +var i = 1<<s // 1 has type int +var j int32 = 1<<s // 1 has type int32; j == 0 +var k = uint64(1<<s) // 1 has type uint64; k == 1<<33 +var m int = 1.0<<s // legal: 1.0 has type int +var n = 1.0<<s != 0 // legal: 1.0 has type int; n == false if ints are 32bits in size +var o = 1<<s == 2<<s // legal: 1 and 2 have type int; o == true if ints are 32bits in size +var p = 1<<s == 1<<33 // illegal if ints are 32bits in size: 1 has type int, but 1<<33 overflows int +var u = 1.0<<s // illegal: 1.0 has type float64, cannot shift +var v float32 = 1<<s // illegal: 1 has type float32, cannot shift +var w int64 = 1.0<<33 // legal: 1.0<<33 is a constant shift expression +</pre> + +<h3 id="Operator_precedence">Operator precedence</h3> +<p> +Unary operators have the highest precedence. +As the <code>++</code> and <code>--</code> operators form +statements, not expressions, they fall +outside the operator hierarchy. +As a consequence, statement <code>*p++</code> is the same as <code>(*p)++</code>. +<p> +There are five precedence levels for binary operators. +Multiplication operators bind strongest, followed by addition +operators, comparison operators, <code>&&</code> (logical and), +and finally <code>||</code> (logical or): +</p> + +<pre class="grammar"> +Precedence Operator + 5 * / % << >> & &^ + 4 + - | ^ + 3 == != < <= > >= + 2 && + 1 || +</pre> + +<p> +Binary operators of the same precedence associate from left to right. +For instance, <code>x / y * z</code> is the same as <code>(x / y) * z</code>. +</p> + +<pre> ++x +23 + 3*x[i] +x <= f() +^a >> b +f() || g() +x == y+1 && <-chan_ptr > 0 +</pre> + + +<h3 id="Arithmetic_operators">Arithmetic operators</h3> +<p> +Arithmetic operators apply to numeric values and yield a result of the same +type as the first operand. The four standard arithmetic operators (<code>+</code>, +<code>-</code>, <code>*</code>, <code>/</code>) apply to integer, +floating-point, and complex types; <code>+</code> also applies +to strings. All other arithmetic operators apply to integers only. +</p> + +<pre class="grammar"> ++ sum integers, floats, complex values, strings +- difference integers, floats, complex values +* product integers, floats, complex values +/ quotient integers, floats, complex values +% remainder integers + +& bitwise and integers +| bitwise or integers +^ bitwise xor integers +&^ bit clear (and not) integers + +<< left shift integer << unsigned integer +>> right shift integer >> unsigned integer +</pre> + +<p> +Strings can be concatenated using the <code>+</code> operator +or the <code>+=</code> assignment operator: +</p> + +<pre> +s := "hi" + string(c) +s += " and good bye" +</pre> + +<p> +String addition creates a new string by concatenating the operands. +</p> +<p> +For two integer values <code>x</code> and <code>y</code>, the integer quotient +<code>q = x / y</code> and remainder <code>r = x % y</code> satisfy the following +relationships: +</p> + +<pre> +x = q*y + r and |r| < |y| +</pre> + +<p> +with <code>x / y</code> truncated towards zero +(<a href="http://en.wikipedia.org/wiki/Modulo_operation">"truncated division"</a>). +</p> + +<pre> + x y x / y x % y + 5 3 1 2 +-5 3 -1 -2 + 5 -3 -1 2 +-5 -3 1 -2 +</pre> + +<p> +As an exception to this rule, if the dividend <code>x</code> is the most +negative value for the int type of <code>x</code>, the quotient +<code>q = x / -1</code> is equal to <code>x</code> (and <code>r = 0</code>). +</p> + +<pre> + x, q +int8 -128 +int16 -32768 +int32 -2147483648 +int64 -9223372036854775808 +</pre> + +<p> +If the divisor is zero, a <a href="#Run_time_panics">run-time panic</a> occurs. +If the dividend is positive and the divisor is a constant power of 2, +the division may be replaced by a right shift, and computing the remainder may +be replaced by a bitwise "and" operation: +</p> + +<pre> + x x / 4 x % 4 x >> 2 x & 3 + 11 2 3 2 3 +-11 -2 -3 -3 1 +</pre> + +<p> +The shift operators shift the left operand by the shift count specified by the +right operand. They implement arithmetic shifts if the left operand is a signed +integer and logical shifts if it is an unsigned integer. +There is no upper limit on the shift count. Shifts behave +as if the left operand is shifted <code>n</code> times by 1 for a shift +count of <code>n</code>. +As a result, <code>x << 1</code> is the same as <code>x*2</code> +and <code>x >> 1</code> is the same as +<code>x/2</code> but truncated towards negative infinity. +</p> + +<p> +For integer operands, the unary operators +<code>+</code>, <code>-</code>, and <code>^</code> are defined as +follows: +</p> + +<pre class="grammar"> ++x is 0 + x +-x negation is 0 - x +^x bitwise complement is m ^ x with m = "all bits set to 1" for unsigned x + and m = -1 for signed x +</pre> + +<p> +For floating-point numbers, +<code>+x</code> is the same as <code>x</code>, +while <code>-x</code> is the negation of <code>x</code>. +The result of a floating-point division by zero is not specified beyond the +IEEE-754 standard; whether a <a href="#Run_time_panics">run-time panic</a> +occurs is implementation-specific. +</p> + +<h3 id="Integer_overflow">Integer overflow</h3> + +<p> +For unsigned integer values, the operations <code>+</code>, +<code>-</code>, <code>*</code>, and <code><<</code> are +computed modulo 2<sup><i>n</i></sup>, where <i>n</i> is the bit width of +the unsigned integer's type +(§<a href="#Numeric_types">Numeric types</a>). Loosely speaking, these unsigned integer operations +discard high bits upon overflow, and programs may rely on ``wrap around''. +</p> +<p> +For signed integers, the operations <code>+</code>, +<code>-</code>, <code>*</code>, and <code><<</code> may legally +overflow and the resulting value exists and is deterministically defined +by the signed integer representation, the operation, and its operands. +No exception is raised as a result of overflow. A +compiler may not optimize code under the assumption that overflow does +not occur. For instance, it may not assume that <code>x < x + 1</code> is always true. +</p> + + +<h3 id="Comparison_operators">Comparison operators</h3> + +<p> +Comparison operators compare two operands and yield a value of type <code>bool</code>. +</p> + +<pre class="grammar"> +== equal +!= not equal +< less +<= less or equal +> greater +>= greater or equal +</pre> + +<p> +The operands must be <i>comparable</i>; that is, the first operand +must be <a href="#Assignability">assignable</a> +to the type of the second operand, or vice versa. +</p> +<p> +The operators <code>==</code> and <code>!=</code> apply +to operands of all types except arrays and structs. +All other comparison operators apply only to integer, floating-point +and string values. The result of a comparison is defined as follows: +</p> + +<ul> + <li> + Integer values are compared in the usual way. + </li> + <li> + Floating point values are compared as defined by the IEEE-754 + standard. + </li> + <li> + Two complex values <code>u</code>, <code>v</code> are + equal if both <code>real(u) == real(v)</code> and + <code>imag(u) == imag(v)</code>. + </li> + <li> + String values are compared byte-wise (lexically). + </li> + <li> + Boolean values are equal if they are either both + <code>true</code> or both <code>false</code>. + </li> + <li> + Pointer values are equal if they point to the same location + or if both are <code>nil</code>. + </li> + <li> + Function values are equal if they refer to the same function + or if both are <code>nil</code>. + </li> + <li> + A slice value may only be compared to <code>nil</code>. + </li> + <li> + Channel and map values are equal if they were created by the same call to <code>make</code> + (§<a href="#Making_slices_maps_and_channels">Making slices, maps, and channels</a>) + or if both are <code>nil</code>. + </li> + <li> + Interface values are equal if they have <a href="#Type_identity">identical</a> dynamic types and + equal dynamic values or if both are <code>nil</code>. + </li> + <li> + An interface value <code>x</code> is equal to a non-interface value + <code>y</code> if the dynamic type of <code>x</code> is identical to + the static type of <code>y</code> and the dynamic value of <code>x</code> + is equal to <code>y</code>. + </li> + <li> + A pointer, function, slice, channel, map, or interface value is equal + to <code>nil</code> if it has been assigned the explicit value + <code>nil</code>, if it is uninitialized, or if it has been assigned + another value equal to <code>nil</code>. + </li> +</ul> + + +<h3 id="Logical_operators">Logical operators</h3> + +<p> +Logical operators apply to <a href="#Boolean_types">boolean</a> values +and yield a result of the same type as the operands. +The right operand is evaluated conditionally. +</p> + +<pre class="grammar"> +&& conditional and p && q is "if p then q else false" +|| conditional or p || q is "if p then true else q" +! not !p is "not p" +</pre> + + +<h3 id="Address_operators">Address operators</h3> + +<p> +For an operand <code>x</code> of type <code>T</code>, the address operation +<code>&x</code> generates a pointer of type <code>*T</code> to <code>x</code>. +The operand must be <i>addressable</i>, +that is, either a variable, pointer indirection, or slice indexing +operation; or a field selector of an addressable struct operand; +or an array indexing operation of an addressable array. +As an exception to the addressability requirement, <code>x</code> may also be a +<a href="#Composite_literals">composite literal</a>. +</p> +<p> +For an operand <code>x</code> of pointer type <code>*T</code>, the pointer +indirection <code>*x</code> denotes the value of type <code>T</code> pointed +to by <code>x</code>. +</p> + +<pre> +&x +&a[f(2)] +*p +*pf(x) +</pre> + + +<h3 id="Receive_operator">Receive operator</h3> + +<p> +For an operand <code>ch</code> of <a href="#Channel_types">channel type</a>, +the value of the receive operation <code><-ch</code> is the value received +from the channel <code>ch</code>. The type of the value is the element type of +the channel. The expression blocks until a value is available. +Receiving from a <code>nil</code> channel blocks forever. +</p> + +<pre> +v1 := <-ch +v2 = <-ch +f(<-ch) +<-strobe // wait until clock pulse and discard received value +</pre> + +<p> +A receive expression used in an assignment or initialization of the form +</p> + +<pre> +x, ok = <-ch +x, ok := <-ch +var x, ok = <-ch +</pre> + +<p> +yields an additional result. +The boolean variable <code>ok</code> indicates whether +the received value was sent on the channel (<code>true</code>) +or is a <a href="#The_zero_value">zero value</a> returned +because the channel is closed and empty (<code>false</code>). +</p> + +<!-- +<p> +<span class="alert">TODO: Probably in a separate section, communication semantics +need to be presented regarding send, receive, select, and goroutines.</span> +</p> +--> + + +<h3 id="Method_expressions">Method expressions</h3> + +<p> +If <code>M</code> is in the <a href="#Method_sets">method set</a> of type <code>T</code>, +<code>T.M</code> is a function that is callable as a regular function +with the same arguments as <code>M</code> prefixed by an additional +argument that is the receiver of the method. +</p> + +<pre class="ebnf"> +MethodExpr = ReceiverType "." MethodName . +ReceiverType = TypeName | "(" "*" TypeName ")" . +</pre> + +<p> +Consider a struct type <code>T</code> with two methods, +<code>Mv</code>, whose receiver is of type <code>T</code>, and +<code>Mp</code>, whose receiver is of type <code>*T</code>. +</p> + +<pre> +type T struct { + a int +} +func (tv T) Mv(a int) int { return 0 } // value receiver +func (tp *T) Mp(f float32) float32 { return 1 } // pointer receiver +var t T +</pre> + +<p> +The expression +</p> + +<pre> +T.Mv +</pre> + +<p> +yields a function equivalent to <code>Mv</code> but +with an explicit receiver as its first argument; it has signature +</p> + +<pre> +func(tv T, a int) int +</pre> + +<p> +That function may be called normally with an explicit receiver, so +these three invocations are equivalent: +</p> + +<pre> +t.Mv(7) +T.Mv(t, 7) +f := T.Mv; f(t, 7) +</pre> + +<p> +Similarly, the expression +</p> + +<pre> +(*T).Mp +</pre> + +<p> +yields a function value representing <code>Mp</code> with signature +</p> + +<pre> +func(tp *T, f float32) float32 +</pre> + +<p> +For a method with a value receiver, one can derive a function +with an explicit pointer receiver, so +</p> + +<pre> +(*T).Mv +</pre> + +<p> +yields a function value representing <code>Mv</code> with signature +</p> + +<pre> +func(tv *T, a int) int +</pre> + +<p> +Such a function indirects through the receiver to create a value +to pass as the receiver to the underlying method; +the method does not overwrite the value whose address is passed in +the function call. +</p> + +<p> +The final case, a value-receiver function for a pointer-receiver method, +is illegal because pointer-receiver methods are not in the method set +of the value type. +</p> + +<p> +Function values derived from methods are called with function call syntax; +the receiver is provided as the first argument to the call. +That is, given <code>f := T.Mv</code>, <code>f</code> is invoked +as <code>f(t, 7)</code> not <code>t.f(7)</code>. +To construct a function that binds the receiver, use a +<a href="#Function_literals">closure</a>. +</p> + +<p> +It is legal to derive a function value from a method of an interface type. +The resulting function takes an explicit receiver of that interface type. +</p> + +<h3 id="Conversions">Conversions</h3> + +<p> +Conversions are expressions of the form <code>T(x)</code> +where <code>T</code> is a type and <code>x</code> is an expression +that can be converted to type <code>T</code>. +</p> + +<pre class="ebnf"> +Conversion = Type "(" Expression ")" . +</pre> + +<p> +If the type starts with an operator it must be parenthesized: +</p> + +<pre> +*Point(p) // same as *(Point(p)) +(*Point)(p) // p is converted to (*Point) +<-chan int(c) // same as <-(chan int(c)) +(<-chan int)(c) // c is converted to (<-chan int) +</pre> + +<p> +A <a href="#Constants">constant</a> value <code>x</code> can be converted to +type <code>T</code> in any of these cases: +</p> + +<ul> + <li> + <code>x</code> is representable by a value of type <code>T</code>. + </li> + <li> + <code>x</code> is an integer constant and <code>T</code> is a + <a href="#String_types">string type</a>. + The same rule as for non-constant <code>x</code> applies in this case + (§<a href="#Conversions_to_and_from_a_string_type">Conversions to and from a string type</a>). + </li> +</ul> + +<p> +Converting a constant yields a typed constant as result. +</p> + +<pre> +uint(iota) // iota value of type uint +float32(2.718281828) // 2.718281828 of type float32 +complex128(1) // 1.0 + 0.0i of type complex128 +string('x') // "x" of type string +string(0x266c) // "♬" of type string +MyString("foo" + "bar") // "foobar" of type MyString +string([]byte{'a'}) // not a constant: []byte{'a'} is not a constant +(*int)(nil) // not a constant: nil is not a constant, *int is not a boolean, numeric, or string type +int(1.2) // illegal: 1.2 cannot be represented as an int +string(65.0) // illegal: 65.0 is not an integer constant +</pre> + +<p> +A non-constant value <code>x</code> can be converted to type <code>T</code> +in any of these cases: +</p> + +<ul> + <li> + <code>x</code> is <a href="#Assignability">assignable</a> + to <code>T</code>. + </li> + <li> + <code>x</code>'s type and <code>T</code> have identical + <a href="#Types">underlying types</a>. + </li> + <li> + <code>x</code>'s type and <code>T</code> are unnamed pointer types + and their pointer base types have identical underlying types. + </li> + <li> + <code>x</code>'s type and <code>T</code> are both integer or floating + point types. + </li> + <li> + <code>x</code>'s type and <code>T</code> are both complex types. + </li> + <li> + <code>x</code> is an integer or has type <code>[]byte</code> or + <code>[]int</code> and <code>T</code> is a string type. + </li> + <li> + <code>x</code> is a string and <code>T</code> is <code>[]byte</code> or + <code>[]int</code>. + </li> +</ul> + +<p> +Specific rules apply to (non-constant) conversions between numeric types or +to and from a string type. +These conversions may change the representation of <code>x</code> +and incur a run-time cost. +All other conversions only change the type but not the representation +of <code>x</code>. +</p> + +<p> +There is no linguistic mechanism to convert between pointers and integers. +The package <a href="#Package_unsafe"><code>unsafe</code></a> +implements this functionality under +restricted circumstances. +</p> + +<h4>Conversions between numeric types</h4> + +<p> +For the conversion of non-constant numeric values, the following rules apply: +</p> + +<ol> +<li> +When converting between integer types, if the value is a signed integer, it is +sign extended to implicit infinite precision; otherwise it is zero extended. +It is then truncated to fit in the result type's size. +For example, if <code>v := uint16(0x10F0)</code>, then <code>uint32(int8(v)) == 0xFFFFFFF0</code>. +The conversion always yields a valid value; there is no indication of overflow. +</li> +<li> +When converting a floating-point number to an integer, the fraction is discarded +(truncation towards zero). +</li> +<li> +When converting an integer or floating-point number to a floating-point type, +or a complex number to another complex type, the result value is rounded +to the precision specified by the destination type. +For instance, the value of a variable <code>x</code> of type <code>float32</code> +may be stored using additional precision beyond that of an IEEE-754 32-bit number, +but float32(x) represents the result of rounding <code>x</code>'s value to +32-bit precision. Similarly, <code>x + 0.1</code> may use more than 32 bits +of precision, but <code>float32(x + 0.1)</code> does not. +</li> +</ol> + +<p> +In all non-constant conversions involving floating-point or complex values, +if the result type cannot represent the value the conversion +succeeds but the result value is implementation-dependent. +</p> + +<h4 id="Conversions_to_and_from_a_string_type">Conversions to and from a string type</h4> + +<ol> +<li> +Converting a signed or unsigned integer value to a string type yields a +string containing the UTF-8 representation of the integer. Values outside +the range of valid Unicode code points are converted to <code>"\uFFFD"</code>. + +<pre> +string('a') // "a" +string(-1) // "\ufffd" == "\xef\xbf\xbd " +string(0xf8) // "\u00f8" == "ø" == "\xc3\xb8" +type MyString string +MyString(0x65e5) // "\u65e5" == "日" == "\xe6\x97\xa5" +</pre> +</li> + +<li> +Converting a value of type <code>[]byte</code> (or +the equivalent <code>[]uint8</code>) to a string type yields a +string whose successive bytes are the elements of the slice. If +the slice value is <code>nil</code>, the result is the empty string. + +<pre> +string([]byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'}) // "hellø" +</pre> +</li> + +<li> +Converting a value of type <code>[]int</code> to a string type yields +a string that is the concatenation of the individual integers +converted to strings. If the slice value is <code>nil</code>, the +result is the empty string. +<pre> +string([]int{0x767d, 0x9d6c, 0x7fd4}) // "\u767d\u9d6c\u7fd4" == "白鵬翔" +</pre> +</li> + +<li> +Converting a value of a string type to <code>[]byte</code> (or <code>[]uint8</code>) +yields a slice whose successive elements are the bytes of the string. +If the string is empty, the result is <code>[]byte(nil)</code>. + +<pre> +[]byte("hellø") // []byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'} +</pre> +</li> + +<li> +Converting a value of a string type to <code>[]int</code> yields a +slice containing the individual Unicode code points of the string. +If the string is empty, the result is <code>[]int(nil)</code>. +<pre> +[]int(MyString("白鵬翔")) // []int{0x767d, 0x9d6c, 0x7fd4} +</pre> +</li> +</ol> + + +<h3 id="Constant_expressions">Constant expressions</h3> + +<p> +Constant expressions may contain only <a href="#Constants">constant</a> +operands and are evaluated at compile-time. +</p> + +<p> +Untyped boolean, numeric, and string constants may be used as operands +wherever it is legal to use an operand of boolean, numeric, or string type, +respectively. Except for shift operations, if the operands of a binary operation +are an untyped integer constant and an untyped floating-point constant, +the integer constant is converted to an untyped floating-point constant +(relevant for <code>/</code> and <code>%</code>). +Similarly, untyped integer or floating-point constants may be used as operands +wherever it is legal to use an operand of complex type; +the integer or floating point constant is converted to a +complex constant with a zero imaginary part. +</p> + +<p> +A constant <a href="#Comparison_operators">comparison</a> always yields +a constant of type <code>bool</code>. If the left operand of a constant +<a href="#Operators">shift expression</a> is an untyped constant, the +result is an integer constant; otherwise it is a constant of the same +type as the left operand, which must be of integer type +(§<a href="#Arithmetic_operators">Arithmetic operators</a>). +Applying all other operators to untyped constants results in an untyped +constant of the same kind (that is, a boolean, integer, floating-point, +complex, or string constant). +</p> + +<pre> +const a = 2 + 3.0 // a == 5.0 (floating-point constant) +const b = 15 / 4 // b == 3 (integer constant) +const c = 15 / 4.0 // c == 3.75 (floating-point constant) +const d = 1 << 3.0 // d == 8 (integer constant) +const e = 1.0 << 3 // e == 8 (integer constant) +const f = int32(1) << 33 // f == 0 (type int32) +const g = float64(2) >> 1 // illegal (float64(2) is a typed floating-point constant) +const h = "foo" > "bar" // h == true (type bool) +</pre> + +<p> +Imaginary literals are untyped complex constants (with zero real part) +and may be combined in binary +operations with untyped integer and floating-point constants; the +result is an untyped complex constant. +Complex constants are always constructed from +constant expressions involving imaginary +literals or constants derived from them, or calls of the built-in function +<a href="#Complex_numbers"><code>complex</code></a>. +</p> + +<pre> +const Σ = 1 - 0.707i +const Δ = Σ + 2.0e-4 - 1/1i +const Φ = iota * 1i +const iΓ = complex(0, Γ) +</pre> + +<p> +Constant expressions are always evaluated exactly; intermediate values and the +constants themselves may require precision significantly larger than supported +by any predeclared type in the language. The following are legal declarations: +</p> + +<pre> +const Huge = 1 << 100 +const Four int8 = Huge >> 98 +</pre> + +<p> +The values of <i>typed</i> constants must always be accurately representable as values +of the constant type. The following constant expressions are illegal: +</p> + +<pre> +uint(-1) // -1 cannot be represented as a uint +int(3.14) // 3.14 cannot be represented as an int +int64(Huge) // 1<<100 cannot be represented as an int64 +Four * 300 // 300 cannot be represented as an int8 +Four * 100 // 400 cannot be represented as an int8 +</pre> + +<p> +The mask used by the unary bitwise complement operator <code>^</code> matches +the rule for non-constants: the mask is all 1s for unsigned constants +and -1 for signed and untyped constants. +</p> + +<pre> +^1 // untyped integer constant, equal to -2 +uint8(^1) // error, same as uint8(-2), out of range +^uint8(1) // typed uint8 constant, same as 0xFF ^ uint8(1) = uint8(0xFE) +int8(^1) // same as int8(-2) +^int8(1) // same as -1 ^ int8(1) = -2 +</pre> + +<!-- +<p> +<span class="alert"> +TODO: perhaps ^ should be disallowed on non-uints instead of assuming twos complement. +Also it may be possible to make typed constants more like variables, at the cost of fewer +overflow etc. errors being caught. +</span> +</p> +--> + +<h3 id="Order_of_evaluation">Order of evaluation</h3> + +<p> +When evaluating the elements of an assignment or expression, +all function calls, method calls and +communication operations are evaluated in lexical left-to-right +order. +</p> + +<p> +For example, in the assignment +</p> +<pre> +y[f()], ok = g(h(), i() + x[j()], <-c), k() +</pre> +<p> +the function calls and communication happen in the order +<code>f()</code>, <code>h()</code>, <code>i()</code>, <code>j()</code>, +<code><-c</code>, <code>g()</code>, and <code>k()</code>. +However, the order of those events compared to the evaluation +and indexing of <code>x</code> and the evaluation +of <code>y</code> is not specified. +</p> + +<p> +Floating-point operations within a single expression are evaluated according to +the associativity of the operators. Explicit parentheses affect the evaluation +by overriding the default associativity. +In the expression <code>x + (y + z)</code> the addition <code>y + z</code> +is performed before adding <code>x</code>. +</p> + +<h2 id="Statements">Statements</h2> + +<p> +Statements control execution. +</p> + +<pre class="ebnf"> +Statement = + Declaration | LabeledStmt | SimpleStmt | + GoStmt | ReturnStmt | BreakStmt | ContinueStmt | GotoStmt | + FallthroughStmt | Block | IfStmt | SwitchStmt | SelectStmt | ForStmt | + DeferStmt . + +SimpleStmt = EmptyStmt | ExpressionStmt | SendStmt | IncDecStmt | Assignment | ShortVarDecl . +</pre> + + +<h3 id="Empty_statements">Empty statements</h3> + +<p> +The empty statement does nothing. +</p> + +<pre class="ebnf"> +EmptyStmt = . +</pre> + + +<h3 id="Labeled_statements">Labeled statements</h3> + +<p> +A labeled statement may be the target of a <code>goto</code>, +<code>break</code> or <code>continue</code> statement. +</p> + +<pre class="ebnf"> +LabeledStmt = Label ":" Statement . +Label = identifier . +</pre> + +<pre> +Error: log.Panic("error encountered") +</pre> + + +<h3 id="Expression_statements">Expression statements</h3> + +<p> +Function calls, method calls, and receive operations +can appear in statement context. Such statements may be parenthesized. +</p> + +<pre class="ebnf"> +ExpressionStmt = Expression . +</pre> + +<pre> +h(x+y) +f.Close() +<-ch +(<-ch) +</pre> + + +<h3 id="Send_statements">Send statements</h3> + +<p> +A send statement sends a value on a channel. +The channel expression must be of <a href="#Channel_types">channel type</a> +and the type of the value must be <a href="#Assignability">assignable</a> +to the channel's element type. +</p> + +<pre class="ebnf"> +SendStmt = Channel "<-" Expression . +Channel = Expression . +</pre> + +<p> +Both the channel and the value expression are evaluated before communication +begins. Communication blocks until the send can proceed, at which point the +value is transmitted on the channel. +A send on an unbuffered channel can proceed if a receiver is ready. +A send on a buffered channel can proceed if there is room in the buffer. +A send on a <code>nil</code> channel blocks forever. +</p> + +<pre> +ch <- 3 +</pre> + + +<h3 id="IncDec_statements">IncDec statements</h3> + +<p> +The "++" and "--" statements increment or decrement their operands +by the untyped <a href="#Constants">constant</a> <code>1</code>. +As with an assignment, the operand must be <a href="#Address_operators">addressable</a> +or a map index expression. +</p> + +<pre class="ebnf"> +IncDecStmt = Expression ( "++" | "--" ) . +</pre> + +<p> +The following <a href="#Assignments">assignment statements</a> are semantically +equivalent: +</p> + +<pre class="grammar"> +IncDec statement Assignment +x++ x += 1 +x-- x -= 1 +</pre> + + +<h3 id="Assignments">Assignments</h3> + +<pre class="ebnf"> +Assignment = ExpressionList assign_op ExpressionList . + +assign_op = [ add_op | mul_op ] "=" . +</pre> + +<p> +Each left-hand side operand must be <a href="#Address_operators">addressable</a>, +a map index expression, or the <a href="#Blank_identifier">blank identifier</a>. +Operands may be parenthesized. +</p> + +<pre> +x = 1 +*p = f() +a[i] = 23 +(k) = <-ch // same as: k = <-ch +</pre> + +<p> +An <i>assignment operation</i> <code>x</code> <i>op</i><code>=</code> +<code>y</code> where <i>op</i> is a binary arithmetic operation is equivalent +to <code>x</code> <code>=</code> <code>x</code> <i>op</i> +<code>y</code> but evaluates <code>x</code> +only once. The <i>op</i><code>=</code> construct is a single token. +In assignment operations, both the left- and right-hand expression lists +must contain exactly one single-valued expression. +</p> + +<pre> +a[i] <<= 2 +i &^= 1<<n +</pre> + +<p> +A tuple assignment assigns the individual elements of a multi-valued +operation to a list of variables. There are two forms. In the +first, the right hand operand is a single multi-valued expression +such as a function evaluation or <a href="#Channel_types">channel</a> or +<a href="#Map_types">map</a> operation or a <a href="#Type_assertions">type assertion</a>. +The number of operands on the left +hand side must match the number of values. For instance, if +<code>f</code> is a function returning two values, +</p> + +<pre> +x, y = f() +</pre> + +<p> +assigns the first value to <code>x</code> and the second to <code>y</code>. +The <a href="#Blank_identifier">blank identifier</a> provides a +way to ignore values returned by a multi-valued expression: +</p> + +<pre> +x, _ = f() // ignore second value returned by f() +</pre> + +<p> +In the second form, the number of operands on the left must equal the number +of expressions on the right, each of which must be single-valued, and the +<i>n</i>th expression on the right is assigned to the <i>n</i>th +operand on the left. +The expressions on the right are evaluated before assigning to +any of the operands on the left, but otherwise the evaluation +order is unspecified beyond <a href="#Order_of_evaluation">the usual rules</a>. +</p> + +<pre> +a, b = b, a // exchange a and b +</pre> + +<p> +In assignments, each value must be +<a href="#Assignability">assignable</a> to the type of the +operand to which it is assigned. If an untyped <a href="#Constants">constant</a> +is assigned to a variable of interface type, the constant is <a href="#Conversions">converted</a> +to type <code>bool</code>, <code>int</code>, <code>float64</code>, +<code>complex128</code> or <code>string</code> +respectively, depending on whether the value is a boolean, integer, floating-point, +complex, or string constant. +</p> + + +<h3 id="If_statements">If statements</h3> + +<p> +"If" statements specify the conditional execution of two branches +according to the value of a boolean expression. If the expression +evaluates to true, the "if" branch is executed, otherwise, if +present, the "else" branch is executed. +</p> + +<pre class="ebnf"> +IfStmt = "if" [ SimpleStmt ";" ] Expression Block [ "else" ( IfStmt | Block ) ] . +</pre> + +<pre> +if x > max { + x = max +} +</pre> + +<p> +The expression may be preceded by a simple statement, which +executes before the expression is evaluated. +</p> + +<pre> +if x := f(); x < y { + return x +} else if x > z { + return z +} else { + return y +} +</pre> + + +<h3 id="Switch_statements">Switch statements</h3> + +<p> +"Switch" statements provide multi-way execution. +An expression or type specifier is compared to the "cases" +inside the "switch" to determine which branch +to execute. +</p> + +<pre class="ebnf"> +SwitchStmt = ExprSwitchStmt | TypeSwitchStmt . +</pre> + +<p> +There are two forms: expression switches and type switches. +In an expression switch, the cases contain expressions that are compared +against the value of the switch expression. +In a type switch, the cases contain types that are compared against the +type of a specially annotated switch expression. +</p> + +<h4 id="Expression_switches">Expression switches</h4> + +<p> +In an expression switch, +the switch expression is evaluated and +the case expressions, which need not be constants, +are evaluated left-to-right and top-to-bottom; the first one that equals the +switch expression +triggers execution of the statements of the associated case; +the other cases are skipped. +If no case matches and there is a "default" case, +its statements are executed. +There can be at most one default case and it may appear anywhere in the +"switch" statement. +A missing switch expression is equivalent to +the expression <code>true</code>. +</p> + +<pre class="ebnf"> +ExprSwitchStmt = "switch" [ SimpleStmt ";" ] [ Expression ] "{" { ExprCaseClause } "}" . +ExprCaseClause = ExprSwitchCase ":" { Statement ";" } . +ExprSwitchCase = "case" ExpressionList | "default" . +</pre> + +<p> +In a case or default clause, +the last statement only may be a "fallthrough" statement +(§<a href="#Fallthrough_statements">Fallthrough statement</a>) to +indicate that control should flow from the end of this clause to +the first statement of the next clause. +Otherwise control flows to the end of the "switch" statement. +</p> + +<p> +The expression may be preceded by a simple statement, which +executes before the expression is evaluated. +</p> + +<pre> +switch tag { +default: s3() +case 0, 1, 2, 3: s1() +case 4, 5, 6, 7: s2() +} + +switch x := f(); { // missing switch expression means "true" +case x < 0: return -x +default: return x +} + +switch { +case x < y: f1() +case x < z: f2() +case x == 4: f3() +} +</pre> + +<h4 id="Type_switches">Type switches</h4> + +<p> +A type switch compares types rather than values. It is otherwise similar +to an expression switch. It is marked by a special switch expression that +has the form of a <a href="#Type_assertions">type assertion</a> +using the reserved word <code>type</code> rather than an actual type. +Cases then match literal types against the dynamic type of the expression +in the type assertion. +</p> + +<pre class="ebnf"> +TypeSwitchStmt = "switch" [ SimpleStmt ";" ] TypeSwitchGuard "{" { TypeCaseClause } "}" . +TypeSwitchGuard = [ identifier ":=" ] PrimaryExpr "." "(" "type" ")" . +TypeCaseClause = TypeSwitchCase ":" { Statement ";" } . +TypeSwitchCase = "case" TypeList | "default" . +TypeList = Type { "," Type } . +</pre> + +<p> +The TypeSwitchGuard may include a +<a href="#Short_variable_declarations">short variable declaration</a>. +When that form is used, the variable is declared in each clause. +In clauses with a case listing exactly one type, the variable +has that type; otherwise, the variable has the type of the expression +in the TypeSwitchGuard. +</p> + +<p> +The type in a case may be <code>nil</code> +(§<a href="#Predeclared_identifiers">Predeclared identifiers</a>); +that case is used when the expression in the TypeSwitchGuard +is a <code>nil</code> interface value. +</p> + +<p> +Given an expression <code>x</code> of type <code>interface{}</code>, +the following type switch: +</p> + +<pre> +switch i := x.(type) { +case nil: + printString("x is nil") +case int: + printInt(i) // i is an int +case float64: + printFloat64(i) // i is a float64 +case func(int) float64: + printFunction(i) // i is a function +case bool, string: + printString("type is bool or string") // i is an interface{} +default: + printString("don't know the type") +} +</pre> + +<p> +could be rewritten: +</p> + +<pre> +v := x // x is evaluated exactly once +if v == nil { + printString("x is nil") +} else if i, is_int := v.(int); is_int { + printInt(i) // i is an int +} else if i, is_float64 := v.(float64); is_float64 { + printFloat64(i) // i is a float64 +} else if i, is_func := v.(func(int) float64); is_func { + printFunction(i) // i is a function +} else { + i1, is_bool := v.(bool) + i2, is_string := v.(string) + if is_bool || is_string { + i := v + printString("type is bool or string") // i is an interface{} + } else { + i := v + printString("don't know the type") // i is an interface{} + } +} +</pre> + +<p> +The type switch guard may be preceded by a simple statement, which +executes before the guard is evaluated. +</p> + +<p> +The "fallthrough" statement is not permitted in a type switch. +</p> + +<h3 id="For_statements">For statements</h3> + +<p> +A "for" statement specifies repeated execution of a block. The iteration is +controlled by a condition, a "for" clause, or a "range" clause. +</p> + +<pre class="ebnf"> +ForStmt = "for" [ Condition | ForClause | RangeClause ] Block . +Condition = Expression . +</pre> + +<p> +In its simplest form, a "for" statement specifies the repeated execution of +a block as long as a boolean condition evaluates to true. +The condition is evaluated before each iteration. +If the condition is absent, it is equivalent to <code>true</code>. +</p> + +<pre> +for a < b { + a *= 2 +} +</pre> + +<p> +A "for" statement with a ForClause is also controlled by its condition, but +additionally it may specify an <i>init</i> +and a <i>post</i> statement, such as an assignment, +an increment or decrement statement. The init statement may be a +<a href="#Short_variable_declarations">short variable declaration</a>, but the post statement must not. +</p> + +<pre class="ebnf"> +ForClause = [ InitStmt ] ";" [ Condition ] ";" [ PostStmt ] . +InitStmt = SimpleStmt . +PostStmt = SimpleStmt . +</pre> + +<pre> +for i := 0; i < 10; i++ { + f(i) +} +</pre> + +<p> +If non-empty, the init statement is executed once before evaluating the +condition for the first iteration; +the post statement is executed after each execution of the block (and +only if the block was executed). +Any element of the ForClause may be empty but the +<a href="#Semicolons">semicolons</a> are +required unless there is only a condition. +If the condition is absent, it is equivalent to <code>true</code>. +</p> + +<pre> +for cond { S() } is the same as for ; cond ; { S() } +for { S() } is the same as for true { S() } +</pre> + +<p> +A "for" statement with a "range" clause +iterates through all entries of an array, slice, string or map, +or values received on a channel. For each entry it assigns <i>iteration values</i> +to corresponding <i>iteration variables</i> and then executes the block. +</p> + +<pre class="ebnf"> +RangeClause = Expression [ "," Expression ] ( "=" | ":=" ) "range" Expression . +</pre> + +<p> +The expression on the right in the "range" clause is called the <i>range expression</i>, +which may be an array, pointer to an array, slice, string, map, or channel. +As with an assignment, the operands on the left must be +<a href="#Address_operators">addressable</a> or map index expressions; they +denote the iteration variables. If the range expression is a channel, only +one iteration variable is permitted, otherwise there may be one or two. +If the second iteration variable is the <a href="#Blank_identifier">blank identifier</a>, +the range clause is equivalent to the same clause with only the first variable present. +</p> + +<p> +The range expression is evaluated once before beginning the loop +except if the expression is an array, in which case, depending on +the expression, it might not be evaluated (see below). +Function calls on the left are evaluated once per iteration. +For each iteration, iteration values are produced as follows: +</p> + +<pre class="grammar"> +Range expression 1st value 2nd value (if 2nd variable is present) + +array or slice a [n]E, *[n]E, or []E index i int a[i] E +string s string type index i int see below int +map m map[K]V key k K m[k] V +channel c chan E element e E +</pre> + +<ol> +<li> +For an array, pointer to array, or slice value <code>a</code>, the index iteration +values are produced in increasing order, starting at element index 0. As a special +case, if only the first iteration variable is present, the range loop produces +iteration values from 0 up to <code>len(a)</code> and does not index into the array +or slice itself. For a <code>nil</code> slice, the number of iterations is 0. +</li> + +<li> +For a string value, the "range" clause iterates over the Unicode code points +in the string starting at byte index 0. On successive iterations, the index value will be the +index of the first byte of successive UTF-8-encoded code points in the string, +and the second value, of type <code>int</code>, will be the value of +the corresponding code point. If the iteration encounters an invalid +UTF-8 sequence, the second value will be <code>0xFFFD</code>, +the Unicode replacement character, and the next iteration will advance +a single byte in the string. +</li> + +<li> +The iteration order over maps is not specified. +If map entries that have not yet been reached are deleted during iteration, +the corresponding iteration values will not be produced. If map entries are +inserted during iteration, the behavior is implementation-dependent, but the +iteration values for each entry will be produced at most once. If the map +is <code>nil</code>, the number of iterations is 0. +</li> + +<li> +For channels, the iteration values produced are the successive values sent on +the channel until the channel is <a href="#Close">closed</a>. If the channel +is <code>nil</code>, the range expression blocks forever. +</li> +</ol> + +<p> +The iteration values are assigned to the respective +iteration variables as in an <a href="#Assignments">assignment statement</a>. +</p> + +<p> +The iteration variables may be declared by the "range" clause (<code>:=</code>). +In this case their types are set to the types of the respective iteration values +and their <a href="#Declarations_and_scope">scope</a> ends at the end of the "for" +statement; they are re-used in each iteration. +If the iteration variables are declared outside the "for" statement, +after execution their values will be those of the last iteration. +</p> + +<pre> +var testdata *struct { + a *[7]int +} +for i, _ := range testdata.a { + // testdata.a is never evaluated; len(testdata.a) is constant + // i ranges from 0 to 6 + f(i) +} + +var a [10]string +m := map[string]int{"mon":0, "tue":1, "wed":2, "thu":3, "fri":4, "sat":5, "sun":6} +for i, s := range a { + // type of i is int + // type of s is string + // s == a[i] + g(i, s) +} + +var key string +var val interface {} // value type of m is assignable to val +for key, val = range m { + h(key, val) +} +// key == last map key encountered in iteration +// val == map[key] + +var ch chan Work = producer() +for w := range ch { + doWork(w) +} +</pre> + + +<h3 id="Go_statements">Go statements</h3> + +<p> +A "go" statement starts the execution of a function or method call +as an independent concurrent thread of control, or <i>goroutine</i>, +within the same address space. +</p> + +<pre class="ebnf"> +GoStmt = "go" Expression . +</pre> + +<p> +The expression must be a call, and +unlike with a regular call, program execution does not wait +for the invoked function to complete. +</p> + +<pre> +go Server() +go func(ch chan<- bool) { for { sleep(10); ch <- true; }} (c) +</pre> + + +<h3 id="Select_statements">Select statements</h3> + +<p> +A "select" statement chooses which of a set of possible communications +will proceed. It looks similar to a "switch" statement but with the +cases all referring to communication operations. +</p> + +<pre class="ebnf"> +SelectStmt = "select" "{" { CommClause } "}" . +CommClause = CommCase ":" { Statement ";" } . +CommCase = "case" ( SendStmt | RecvStmt ) | "default" . +RecvStmt = [ Expression [ "," Expression ] ( "=" | ":=" ) ] RecvExpr . +RecvExpr = Expression . +</pre> + +<p> +RecvExpr must be a <a href="#Receive_operator">receive operation</a>. +For all the cases in the "select" +statement, the channel expressions are evaluated in top-to-bottom order, along with +any expressions that appear on the right hand side of send statements. +A channel may be <code>nil</code>, +which is equivalent to that case not +being present in the select statement +except, if a send, its expression is still evaluated. +If any of the resulting operations can proceed, one of those is +chosen and the corresponding communication and statements are +evaluated. Otherwise, if there is a default case, that executes; +if there is no default case, the statement blocks until one of the communications can +complete. +If there are no cases with non-<code>nil</code> channels, +the statement blocks forever. +Even if the statement blocks, +the channel and send expressions are evaluated only once, +upon entering the select statement. +</p> +<p> +Since all the channels and send expressions are evaluated, any side +effects in that evaluation will occur for all the communications +in the "select" statement. +</p> +<p> +If multiple cases can proceed, a pseudo-random fair choice is made to decide +which single communication will execute. +<p> +The receive case may declare one or two new variables using a +<a href="#Short_variable_declarations">short variable declaration</a>. +</p> + +<pre> +var c, c1, c2, c3 chan int +var i1, i2 int +select { +case i1 = <-c1: + print("received ", i1, " from c1\n") +case c2 <- i2: + print("sent ", i2, " to c2\n") +case i3, ok := (<-c3): // same as: i3, ok := <-c3 + if ok { + print("received ", i3, " from c3\n") + } else { + print("c3 is closed\n") + } +default: + print("no communication\n") +} + +for { // send random sequence of bits to c + select { + case c <- 0: // note: no statement, no fallthrough, no folding of cases + case c <- 1: + } +} + +select { } // block forever +</pre> + + +<h3 id="Return_statements">Return statements</h3> + +<p> +A "return" statement terminates execution of the containing function +and optionally provides a result value or values to the caller. +</p> + +<pre class="ebnf"> +ReturnStmt = "return" [ ExpressionList ] . +</pre> + +<p> +In a function without a result type, a "return" statement must not +specify any result values. +</p> +<pre> +func no_result() { + return +} +</pre> + +<p> +There are three ways to return values from a function with a result +type: +</p> + +<ol> + <li>The return value or values may be explicitly listed + in the "return" statement. Each expression must be single-valued + and <a href="#Assignability">assignable</a> + to the corresponding element of the function's result type. +<pre> +func simple_f() int { + return 2 +} + +func complex_f1() (re float64, im float64) { + return -7.0, -4.0 +} +</pre> + </li> + <li>The expression list in the "return" statement may be a single + call to a multi-valued function. The effect is as if each value + returned from that function were assigned to a temporary + variable with the type of the respective value, followed by a + "return" statement listing these variables, at which point the + rules of the previous case apply. +<pre> +func complex_f2() (re float64, im float64) { + return complex_f1() +} +</pre> + </li> + <li>The expression list may be empty if the function's result + type specifies names for its result parameters (§<a href="#Function_types">Function Types</a>). + The result parameters act as ordinary local variables + and the function may assign values to them as necessary. + The "return" statement returns the values of these variables. +<pre> +func complex_f3() (re float64, im float64) { + re = 7.0 + im = 4.0 + return +} + +func (devnull) Write(p []byte) (n int, _ os.Error) { + n = len(p) + return +} +</pre> + </li> +</ol> + +<p> +Regardless of how they are declared, all the result values are initialized to the zero values for their type (§<a href="#The_zero_value">The zero value</a>) upon entry to the function. +</p> + +<!-- +<p> +<span class="alert"> +TODO: Define when return is required.<br /> +TODO: Language about result parameters needs to go into a section on + function/method invocation<br /> +</span> +</p> +--> + +<h3 id="Break_statements">Break statements</h3> + +<p> +A "break" statement terminates execution of the innermost +"for", "switch" or "select" statement. +</p> + +<pre class="ebnf"> +BreakStmt = "break" [ Label ] . +</pre> + +<p> +If there is a label, it must be that of an enclosing +"for", "switch" or "select" statement, and that is the one whose execution +terminates +(§<a href="#For_statements">For statements</a>, §<a href="#Switch_statements">Switch statements</a>, §<a href="#Select_statements">Select statements</a>). +</p> + +<pre> +L: + for i < n { + switch i { + case 5: + break L + } + } +</pre> + +<h3 id="Continue_statements">Continue statements</h3> + +<p> +A "continue" statement begins the next iteration of the +innermost "for" loop at its post statement (§<a href="#For_statements">For statements</a>). +</p> + +<pre class="ebnf"> +ContinueStmt = "continue" [ Label ] . +</pre> + +<p> +If there is a label, it must be that of an enclosing +"for" statement, and that is the one whose execution +advances +(§<a href="#For_statements">For statements</a>). +</p> + +<h3 id="Goto_statements">Goto statements</h3> + +<p> +A "goto" statement transfers control to the statement with the corresponding label. +</p> + +<pre class="ebnf"> +GotoStmt = "goto" Label . +</pre> + +<pre> +goto Error +</pre> + +<p> +Executing the "goto" statement must not cause any variables to come into +<a href="#Declarations_and_scope">scope</a> that were not already in scope at the point of the goto. +For instance, this example: +</p> + +<pre> + goto L // BAD + v := 3 +L: +</pre> + +<p> +is erroneous because the jump to label <code>L</code> skips +the creation of <code>v</code>. +</p> + +<p> +A "goto" statement outside a <a href="#Blocks">block</a> cannot jump to a label inside that block. +For instance, this example: +</p> + +<pre> +if n%2 == 1 { + goto L1 +} +for n > 0 { + f() + n-- +L1: + f() + n-- +} +</pre> + +<p> +is erroneous because the label <code>L1</code> is inside +the "for" statement's block but the <code>goto</code> is not. +</p> + +<h3 id="Fallthrough_statements">Fallthrough statements</h3> + +<p> +A "fallthrough" statement transfers control to the first statement of the +next case clause in a expression "switch" statement (§<a href="#Expression_switches">Expression switches</a>). It may +be used only as the final non-empty statement in a case or default clause in an +expression "switch" statement. +</p> + +<pre class="ebnf"> +FallthroughStmt = "fallthrough" . +</pre> + + +<h3 id="Defer_statements">Defer statements</h3> + +<p> +A "defer" statement invokes a function whose execution is deferred to the moment +the surrounding function returns. +</p> + +<pre class="ebnf"> +DeferStmt = "defer" Expression . +</pre> + +<p> +The expression must be a function or method call. +Each time the "defer" statement +executes, the parameters to the function call are evaluated and saved anew but the +function is not invoked. +Deferred function calls are executed in LIFO order +immediately before the surrounding function returns, +after the return values, if any, have been evaluated, but before they +are returned to the caller. For instance, if the deferred function is +a <a href="#Function_literals">function literal</a> and the surrounding +function has <a href="#Function_types">named result parameters</a> that +are in scope within the literal, the deferred function may access and modify +the result parameters before they are returned. +</p> + +<pre> +lock(l) +defer unlock(l) // unlocking happens before surrounding function returns + +// prints 3 2 1 0 before surrounding function returns +for i := 0; i <= 3; i++ { + defer fmt.Print(i) +} + +// f returns 1 +func f() (result int) { + defer func() { + result++ + }() + return 0 +} +</pre> + +<h2 id="Built-in_functions">Built-in functions</h2> + +<p> +Built-in functions are +<a href="#Predeclared_identifiers">predeclared</a>. +They are called like any other function but some of them +accept a type instead of an expression as the first argument. +</p> + +<p> +The built-in functions do not have standard Go types, +so they can only appear in <a href="#Calls">call expressions</a>; +they cannot be used as function values. +</p> + +<pre class="ebnf"> +BuiltinCall = identifier "(" [ BuiltinArgs [ "," ] ] ")" . +BuiltinArgs = Type [ "," ExpressionList ] | ExpressionList . +</pre> + +<h3 id="Close">Close</h3> + +<p> +For a channel <code>c</code>, the built-in function <code>close(c)</code> +marks the channel as unable to accept more values through a send operation; +sending to or closing a closed channel causes a <a href="#Run_time_panics">run-time panic</a>. +After calling <code>close</code>, and after any previously +sent values have been received, receive operations will return +the zero value for the channel's type without blocking. + +The multi-valued <a href="#Receive_operator">receive operation</a> +returns a received value along with an indication of whether the channel is closed. +</p> + + +<h3 id="Length_and_capacity">Length and capacity</h3> + +<p> +The built-in functions <code>len</code> and <code>cap</code> take arguments +of various types and return a result of type <code>int</code>. +The implementation guarantees that the result always fits into an <code>int</code>. +</p> + +<pre class="grammar"> +Call Argument type Result + +len(s) string type string length in bytes + [n]T, *[n]T array length (== n) + []T slice length + map[K]T map length (number of defined keys) + chan T number of elements queued in channel buffer + +cap(s) [n]T, *[n]T array length (== n) + []T slice capacity + chan T channel buffer capacity +</pre> + +<p> +The capacity of a slice is the number of elements for which there is +space allocated in the underlying array. +At any time the following relationship holds: +</p> + +<pre> +0 <= len(s) <= cap(s) +</pre> + +<p> +The length and capacity of a <code>nil</code> slice, map, or channel are 0. +</p> + +<p> +The expression <code>len(s)</code> is <a href="#Constants">constant</a> if +<code>s</code> is a string constant. The expressions <code>len(s)</code> and +<code>cap(s)</code> are constants if the type of <code>s</code> is an array +or pointer to an array and the expression <code>s</code> does not contain +<a href="#Receive_operator">channel receives</a> or +<a href="#Calls">function calls</a>; in this case <code>s</code> is not evaluated. +Otherwise, invocations of <code>len</code> and <code>cap</code> are not +constant and <code>s</code> is evaluated. +</p> + + +<h3 id="Allocation">Allocation</h3> + +<p> +The built-in function <code>new</code> takes a type <code>T</code> and +returns a value of type <code>*T</code>. +The memory is initialized as described in the section on initial values +(§<a href="#The_zero_value">The zero value</a>). +</p> + +<pre class="grammar"> +new(T) +</pre> + +<p> +For instance +</p> + +<pre> +type S struct { a int; b float64 } +new(S) +</pre> + +<p> +dynamically allocates memory for a variable of type <code>S</code>, +initializes it (<code>a=0</code>, <code>b=0.0</code>), +and returns a value of type <code>*S</code> containing the address +of the memory. +</p> + +<h3 id="Making_slices_maps_and_channels">Making slices, maps and channels</h3> + +<p> +Slices, maps and channels are reference types that do not require the +extra indirection of an allocation with <code>new</code>. +The built-in function <code>make</code> takes a type <code>T</code>, +which must be a slice, map or channel type, +optionally followed by a type-specific list of expressions. +It returns a value of type <code>T</code> (not <code>*T</code>). +The memory is initialized as described in the section on initial values +(§<a href="#The_zero_value">The zero value</a>). +</p> + +<pre class="grammar"> +Call Type T Result + +make(T, n) slice slice of type T with length n and capacity n +make(T, n, m) slice slice of type T with length n and capacity m + +make(T) map map of type T +make(T, n) map map of type T with initial space for n elements + +make(T) channel synchronous channel of type T +make(T, n) channel asynchronous channel of type T, buffer size n +</pre> + + +<p> +The arguments <code>n</code> and <code>m</code> must be of integer type. +A <a href="#Run_time_panics">run-time panic</a> occurs if <code>n</code> +is negative or larger than <code>m</code>, or if <code>n</code> or +<code>m</code> cannot be represented by an <code>int</code>. +</p> + +<pre> +s := make([]int, 10, 100) // slice with len(s) == 10, cap(s) == 100 +s := make([]int, 10) // slice with len(s) == cap(s) == 10 +c := make(chan int, 10) // channel with a buffer size of 10 +m := make(map[string] int, 100) // map with initial space for 100 elements +</pre> + + +<h3 id="Appending_and_copying_slices">Appending to and copying slices</h3> + +<p> +Two built-in functions assist in common slice operations. +</p> + +<p> +The <a href="#Function_types">variadic</a> function <code>append</code> +appends zero or more values <code>x</code> +to <code>s</code> of type <code>S</code>, which must be a slice type, and +returns the resulting slice, also of type <code>S</code>. +The values <code>x</code> are passed to a parameter of type <code>...T</code> +where <code>T</code> is the <a href="#Slice_types">element type</a> of +<code>S</code> and the respective +<a href="#Passing_arguments_to_..._parameters">parameter passing rules</a> apply. +</p> + +<pre class="grammar"> +append(s S, x ...T) S // T is the element type of S +</pre> + +<p> +If the capacity of <code>s</code> is not large enough to fit the additional +values, <code>append</code> allocates a new, sufficiently large slice that fits +both the existing slice elements and the additional values. Thus, the returned +slice may refer to a different underlying array. +</p> + +<pre> +s0 := []int{0, 0} +s1 := append(s0, 2) // append a single element s1 == []int{0, 0, 2} +s2 := append(s1, 3, 5, 7) // append multiple elements s2 == []int{0, 0, 2, 3, 5, 7} +s3 := append(s2, s0...) // append a slice s3 == []int{0, 0, 2, 3, 5, 7, 0, 0} + +var t []interface{} +t = append(t, 42, 3.1415, "foo") t == []interface{}{42, 3.1415, "foo"} +</pre> + +<p> +The function <code>copy</code> copies slice elements from +a source <code>src</code> to a destination <code>dst</code> and returns the +number of elements copied. Source and destination may overlap. +Both arguments must have <a href="#Type_identity">identical</a> element type <code>T</code> and must be +<a href="#Assignability">assignable</a> to a slice of type <code>[]T</code>. +The number of elements copied is the minimum of +<code>len(src)</code> and <code>len(dst)</code>. +As a special case, <code>copy</code> also accepts a destination argument assignable +to type <code>[]byte</code> with a source argument of a string type. +This form copies the bytes from the string into the byte slice. +</p> + +<pre class="grammar"> +copy(dst, src []T) int +copy(dst []byte, src string) int +</pre> + +<p> +Examples: +</p> + +<pre> +var a = [...]int{0, 1, 2, 3, 4, 5, 6, 7} +var s = make([]int, 6) +var b = make([]byte, 5) +n1 := copy(s, a[0:]) // n1 == 6, s == []int{0, 1, 2, 3, 4, 5} +n2 := copy(s, s[2:]) // n2 == 4, s == []int{2, 3, 4, 5, 4, 5} +n3 := copy(b, "Hello, World!") // n3 == 5, b == []byte("Hello") +</pre> + +<h3 id="Complex_numbers">Assembling and disassembling complex numbers</h3> + +<p> +Three functions assemble and disassemble complex numbers. +The built-in function <code>complex</code> constructs a complex +value from a floating-point real and imaginary part, while +<code>real</code> and <code>imag</code> +extract the real and imaginary parts of a complex value. +</p> + +<pre class="grammar"> +complex(realPart, imaginaryPart floatT) complexT +real(complexT) floatT +imag(complexT) floatT +</pre> + +<p> +The type of the arguments and return value correspond. +For <code>complex</code>, the two arguments must be of the same +floating-point type and the return type is the complex type +with the corresponding floating-point constituents: +<code>complex64</code> for <code>float32</code>, +<code>complex128</code> for <code>float64</code>. +The <code>real</code> and <code>imag</code> functions +together form the inverse, so for a complex value <code>z</code>, +<code>z</code> <code>==</code> <code>complex(real(z),</code> <code>imag(z))</code>. +</p> + +<p> +If the operands of these functions are all constants, the return +value is a constant. +</p> + +<pre> +var a = complex(2, -2) // complex128 +var b = complex(1.0, -1.4) // complex128 +x := float32(math.Cos(math.Pi/2)) // float32 +var c64 = complex(5, -x) // complex64 +var im = imag(b) // float64 +var rl = real(c64) // float32 +</pre> + +<h3 id="Handling_panics">Handling panics</h3> + +<p> Two built-in functions, <code>panic</code> and <code>recover</code>, +assist in reporting and handling <a href="#Run_time_panics">run-time panics</a> +and program-defined error conditions. +</p> + +<pre class="grammar"> +func panic(interface{}) +func recover() interface{} +</pre> + +<p> +When a function <code>F</code> calls <code>panic</code>, normal +execution of <code>F</code> stops immediately. Any functions whose +execution was <a href="#Defer_statements">deferred</a> by the +invocation of <code>F</code> are run in the usual way, and then +<code>F</code> returns to its caller. To the caller, <code>F</code> +then behaves like a call to <code>panic</code>, terminating its own +execution and running deferred functions. This continues until all +functions in the goroutine have ceased execution, in reverse order. +At that point, the program is +terminated and the error condition is reported, including the value of +the argument to <code>panic</code>. This termination sequence is +called <i>panicking</i>. +</p> + +<pre> +panic(42) +panic("unreachable") +panic(Error("cannot parse")) +</pre> + +<p> +The <code>recover</code> function allows a program to manage behavior +of a panicking goroutine. Executing a <code>recover</code> call +<i>inside</i> a deferred function (but not any function called by it) stops +the panicking sequence by restoring normal execution, and retrieves +the error value passed to the call of <code>panic</code>. If +<code>recover</code> is called outside the deferred function it will +not stop a panicking sequence. In this case, or when the goroutine +is not panicking, or if the argument supplied to <code>panic</code> +was <code>nil</code>, <code>recover</code> returns <code>nil</code>. +</p> + +<p> +The <code>protect</code> function in the example below invokes +the function argument <code>g</code> and protects callers from +run-time panics raised by <code>g</code>. +</p> + +<pre> +func protect(g func()) { + defer func() { + log.Println("done") // Println executes normally even in there is a panic + if x := recover(); x != nil { + log.Printf("run time panic: %v", x) + } + }() + log.Println("start") + g() +} +</pre> + + +<h3 id="Bootstrapping">Bootstrapping</h3> + +<p> +Current implementations provide several built-in functions useful during +bootstrapping. These functions are documented for completeness but are not +guaranteed to stay in the language. They do not return a result. +</p> + +<pre class="grammar"> +Function Behavior + +print prints all arguments; formatting of arguments is implementation-specific +println like print but prints spaces between arguments and a newline at the end +</pre> + + +<h2 id="Packages">Packages</h2> + +<p> +Go programs are constructed by linking together <i>packages</i>. +A package in turn is constructed from one or more source files +that together declare constants, types, variables and functions +belonging to the package and which are accessible in all files +of the same package. Those elements may be +<a href="#Exported_identifiers">exported</a> and used in another package. +</p> + +<h3 id="Source_file_organization">Source file organization</h3> + +<p> +Each source file consists of a package clause defining the package +to which it belongs, followed by a possibly empty set of import +declarations that declare packages whose contents it wishes to use, +followed by a possibly empty set of declarations of functions, +types, variables, and constants. +</p> + +<pre class="ebnf"> +SourceFile = PackageClause ";" { ImportDecl ";" } { TopLevelDecl ";" } . +</pre> + +<h3 id="Package_clause">Package clause</h3> + +<p> +A package clause begins each source file and defines the package +to which the file belongs. +</p> + +<pre class="ebnf"> +PackageClause = "package" PackageName . +PackageName = identifier . +</pre> + +<p> +The PackageName must not be the <a href="#Blank_identifier">blank identifier</a>. +</p> + +<pre> +package math +</pre> + +<p> +A set of files sharing the same PackageName form the implementation of a package. +An implementation may require that all source files for a package inhabit the same directory. +</p> + +<h3 id="Import_declarations">Import declarations</h3> + +<p> +An import declaration states that the source file containing the +declaration uses identifiers +<a href="#Exported_identifiers">exported</a> by the <i>imported</i> +package and enables access to them. The import names an +identifier (PackageName) to be used for access and an ImportPath +that specifies the package to be imported. +</p> + +<pre class="ebnf"> +ImportDecl = "import" ( ImportSpec | "(" { ImportSpec ";" } ")" ) . +ImportSpec = [ "." | PackageName ] ImportPath . +ImportPath = string_lit . +</pre> + +<p> +The PackageName is used in <a href="#Qualified_identifiers">qualified identifiers</a> +to access the exported identifiers of the package within the importing source file. +It is declared in the <a href="#Blocks">file block</a>. +If the PackageName is omitted, it defaults to the identifier specified in the +<a href="#Package_clause">package clause</a> of the imported package. +If an explicit period (<code>.</code>) appears instead of a name, all the +package's exported identifiers will be declared in the current file's +file block and can be accessed without a qualifier. +</p> + +<p> +The interpretation of the ImportPath is implementation-dependent but +it is typically a substring of the full file name of the compiled +package and may be relative to a repository of installed packages. +</p> + +<p> +Assume we have compiled a package containing the package clause +<code>package math</code>, which exports function <code>Sin</code>, and +installed the compiled package in the file identified by +<code>"lib/math"</code>. +This table illustrates how <code>Sin</code> may be accessed in files +that import the package after the +various types of import declaration. +</p> + +<pre class="grammar"> +Import declaration Local name of Sin + +import "lib/math" math.Sin +import M "lib/math" M.Sin +import . "lib/math" Sin +</pre> + +<p> +An import declaration declares a dependency relation between +the importing and imported package. +It is illegal for a package to import itself or to import a package without +referring to any of its exported identifiers. To import a package solely for +its side-effects (initialization), use the <a href="#Blank_identifier">blank</a> +identifier as explicit package name: +</p> + +<pre> +import _ "lib/math" +</pre> + + +<h3 id="An_example_package">An example package</h3> + +<p> +Here is a complete Go package that implements a concurrent prime sieve. +</p> + +<pre> +package main + +import "fmt" + +// Send the sequence 2, 3, 4, … to channel 'ch'. +func generate(ch chan<- int) { + for i := 2; ; i++ { + ch <- i // Send 'i' to channel 'ch'. + } +} + +// Copy the values from channel 'src' to channel 'dst', +// removing those divisible by 'prime'. +func filter(src <-chan int, dst chan<- int, prime int) { + for i := range src { // Loop over values received from 'src'. + if i%prime != 0 { + dst <- i // Send 'i' to channel 'dst'. + } + } +} + +// The prime sieve: Daisy-chain filter processes together. +func sieve() { + ch := make(chan int) // Create a new channel. + go generate(ch) // Start generate() as a subprocess. + for { + prime := <-ch + fmt.Print(prime, "\n") + ch1 := make(chan int) + go filter(ch, ch1, prime) + ch = ch1 + } +} + +func main() { + sieve() +} +</pre> + +<h2 id="Program_initialization_and_execution">Program initialization and execution</h2> + +<h3 id="The_zero_value">The zero value</h3> +<p> +When memory is allocated to store a value, either through a declaration +or a call of <code>make</code> or <code>new</code>, +and no explicit initialization is provided, the memory is +given a default initialization. Each element of such a value is +set to the <i>zero value</i> for its type: <code>false</code> for booleans, +<code>0</code> for integers, <code>0.0</code> for floats, <code>""</code> +for strings, and <code>nil</code> for pointers, functions, interfaces, slices, channels, and maps. +This initialization is done recursively, so for instance each element of an +array of structs will have its fields zeroed if no value is specified. +</p> +<p> +These two simple declarations are equivalent: +</p> + +<pre> +var i int +var i int = 0 +</pre> + +<p> +After +</p> + +<pre> +type T struct { i int; f float64; next *T } +t := new(T) +</pre> + +<p> +the following holds: +</p> + +<pre> +t.i == 0 +t.f == 0.0 +t.next == nil +</pre> + +<p> +The same would also be true after +</p> + +<pre> +var t T +</pre> + +<h3 id="Program_execution">Program execution</h3> +<p> +A package with no imports is initialized by assigning initial values to +all its package-level variables +and then calling any +package-level function with the name and signature of +</p> +<pre> +func init() +</pre> +<p> +defined in its source. +A package may contain multiple +<code>init</code> functions, even +within a single source file; they execute +in unspecified order. +</p> +<p> +Within a package, package-level variables are initialized, +and constant values are determined, in +data-dependent order: if the initializer of <code>A</code> +depends on the value of <code>B</code>, <code>A</code> +will be set after <code>B</code>. +It is an error if such dependencies form a cycle. +Dependency analysis is done lexically: <code>A</code> +depends on <code>B</code> if the value of <code>A</code> +contains a mention of <code>B</code>, contains a value +whose initializer +mentions <code>B</code>, or mentions a function that +mentions <code>B</code>, recursively. +If two items are not interdependent, they will be initialized +in the order they appear in the source. +Since the dependency analysis is done per package, it can produce +unspecified results if <code>A</code>'s initializer calls a function defined +in another package that refers to <code>B</code>. +</p> +<p> +Initialization code may contain "go" statements, but the functions +they invoke do not begin execution until initialization of the entire +program is complete. Therefore, all initialization code is run in a single +goroutine. +</p> +<p> +An <code>init</code> function cannot be referred to from anywhere +in a program. In particular, <code>init</code> cannot be called explicitly, +nor can a pointer to <code>init</code> be assigned to a function variable. +</p> +<p> +If a package has imports, the imported packages are initialized +before initializing the package itself. If multiple packages import +a package <code>P</code>, <code>P</code> will be initialized only once. +</p> +<p> +The importing of packages, by construction, guarantees that there can +be no cyclic dependencies in initialization. +</p> +<p> +A complete program is created by linking a single, unimported package +called the <i>main package</i> with all the packages it imports, transitively. +The main package must +have package name <code>main</code> and +declare a function <code>main</code> that takes no +arguments and returns no value. +</p> + +<pre> +func main() { … } +</pre> + +<p> +Program execution begins by initializing the main package and then +invoking the function <code>main</code>. +</p> +<p> +When the function <code>main</code> returns, the program exits. +It does not wait for other (non-<code>main</code>) goroutines to complete. +</p> + +<h2 id="Run_time_panics">Run-time panics</h2> + +<p> +Execution errors such as attempting to index an array out +of bounds trigger a <i>run-time panic</i> equivalent to a call of +the built-in function <a href="#Handling_panics"><code>panic</code></a> +with a value of the implementation-defined interface type <code>runtime.Error</code>. +That type defines at least the method +<code>String() string</code>. The exact error values that +represent distinct run-time error conditions are unspecified, +at least for now. +</p> + +<pre> +package runtime + +type Error interface { + String() string + // and perhaps others +} +</pre> + +<h2 id="System_considerations">System considerations</h2> + +<h3 id="Package_unsafe">Package <code>unsafe</code></h3> + +<p> +The built-in package <code>unsafe</code>, known to the compiler, +provides facilities for low-level programming including operations +that violate the type system. A package using <code>unsafe</code> +must be vetted manually for type safety. The package provides the +following interface: +</p> + +<pre class="grammar"> +package unsafe + +type ArbitraryType int // shorthand for an arbitrary Go type; it is not a real type +type Pointer *ArbitraryType + +func Alignof(variable ArbitraryType) uintptr +func Offsetof(selector ArbitraryType) uinptr +func Sizeof(variable ArbitraryType) uintptr + +func Reflect(val interface{}) (typ runtime.Type, addr uintptr) +func Typeof(val interface{}) (typ interface{}) +func Unreflect(typ runtime.Type, addr uintptr) interface{} +</pre> + +<p> +Any pointer or value of type <code>uintptr</code> can be converted into +a <code>Pointer</code> and vice versa. +</p> +<p> +The function <code>Sizeof</code> takes an expression denoting a +variable of any type and returns the size of the variable in bytes. +</p> +<p> +The function <code>Offsetof</code> takes a selector (§<a href="#Selectors">Selectors</a>) denoting a struct +field of any type and returns the field offset in bytes relative to the +struct's address. +For a struct <code>s</code> with field <code>f</code>: +</p> + +<pre> +uintptr(unsafe.Pointer(&s)) + unsafe.Offsetof(s.f) == uintptr(unsafe.Pointer(&s.f)) +</pre> + +<p> +Computer architectures may require memory addresses to be <i>aligned</i>; +that is, for addresses of a variable to be a multiple of a factor, +the variable's type's <i>alignment</i>. The function <code>Alignof</code> +takes an expression denoting a variable of any type and returns the +alignment of the (type of the) variable in bytes. For a variable +<code>x</code>: +</p> + +<pre> +uintptr(unsafe.Pointer(&x)) % unsafe.Alignof(x) == 0 +</pre> + +<p> +Calls to <code>Alignof</code>, <code>Offsetof</code>, and +<code>Sizeof</code> are compile-time constant expressions of type <code>uintptr</code>. +</p> +<p> +The functions <code>unsafe.Typeof</code>, +<code>unsafe.Reflect</code>, +and <code>unsafe.Unreflect</code> allow access at run time to the dynamic +types and values stored in interfaces. +<code>Typeof</code> returns a representation of +<code>val</code>'s +dynamic type as a <code>runtime.Type</code>. +<code>Reflect</code> allocates a copy of +<code>val</code>'s dynamic +value and returns both the type and the address of the copy. +<code>Unreflect</code> inverts <code>Reflect</code>, +creating an +interface value from a type and address. +The <a href="/pkg/reflect/"><code>reflect</code> package</a> built on these primitives +provides a safe, more convenient way to inspect interface values. +</p> + + +<h3 id="Size_and_alignment_guarantees">Size and alignment guarantees</h3> + +<p> +For the numeric types (§<a href="#Numeric_types">Numeric types</a>), the following sizes are guaranteed: +</p> + +<pre class="grammar"> +type size in bytes + +byte, uint8, int8 1 +uint16, int16 2 +uint32, int32, float32 4 +uint64, int64, float64, complex64 8 +complex128 16 +</pre> + +<p> +The following minimal alignment properties are guaranteed: +</p> +<ol> +<li>For a variable <code>x</code> of any type: <code>unsafe.Alignof(x)</code> is at least 1. +</li> + +<li>For a variable <code>x</code> of struct type: <code>unsafe.Alignof(x)</code> is the largest of + all the values <code>unsafe.Alignof(x.f)</code> for each field <code>f</code> of <code>x</code>, but at least 1. +</li> + +<li>For a variable <code>x</code> of array type: <code>unsafe.Alignof(x)</code> is the same as + <code>unsafe.Alignof(x[0])</code>, but at least 1. +</li> +</ol> + +<span class="alert"> +<h2 id="Implementation_differences">Implementation differences - TODO</h2> +<ul> + <li><code>len(a)</code> is only a constant if <code>a</code> is a (qualified) identifier denoting an array or pointer to an array.</li> + <li><code>nil</code> maps are not treated like empty maps.</li> + <li>Trying to send/receive from a <code>nil</code> channel causes a run-time panic.</li> + <li><code>unsafe.Alignof</code>, <code>unsafe.Offsetof</code>, and <code>unsafe.Sizeof</code> return an <code>int</code>.</li> +</ul> +</span> diff --git a/doc/go_tutorial.html b/doc/go_tutorial.html new file mode 100644 index 000000000..0b366bb2b --- /dev/null +++ b/doc/go_tutorial.html @@ -0,0 +1,1455 @@ +<!-- A Tutorial for the Go Programming Language --> +<h2>Introduction</h2> +<p> +This document is a tutorial introduction to the basics of the Go programming +language, intended for programmers familiar with C or C++. It is not a comprehensive +guide to the language; at the moment the document closest to that is the +<a href='/doc/go_spec.html'>language specification</a>. +After you've read this tutorial, you should look at +<a href='/doc/effective_go.html'>Effective Go</a>, +which digs deeper into how the language is used and +talks about the style and idioms of programming in Go. +Also, slides from a 3-day course about Go are available. +They provide some background and a lot of examples: +<a href='/doc/GoCourseDay1.pdf'>Day 1</a>, +<a href='/doc/GoCourseDay2.pdf'>Day 2</a>, +<a href='/doc/GoCourseDay3.pdf'>Day 3</a>. +<p> +The presentation here proceeds through a series of modest programs to illustrate +key features of the language. All the programs work (at time of writing) and are +checked into the repository in the directory <a href='/doc/progs'><code>/doc/progs/</code></a>. +<p> +<h2>Hello, World</h2> +<p> +Let's start in the usual way: +<p> +<pre><!--{{code "progs/helloworld.go" `/package/` "$"}} +-->package main + +import fmt "fmt" // Package implementing formatted I/O. + +func main() { + fmt.Printf("Hello, world; or Καλημέρα κόσμε; or こんにちは 世界\n") +} +</pre> +<p> +Every Go source file declares, using a <code>package</code> statement, which package it's part of. +It may also import other packages to use their facilities. +This program imports the package <code>fmt</code> to gain access to +our old, now capitalized and package-qualified, friend, <code>fmt.Printf</code>. +<p> +Functions are introduced with the <code>func</code> keyword. +The <code>main</code> package's <code>main</code> function is where the program starts running (after +any initialization). +<p> +String constants can contain Unicode characters, encoded in UTF-8. +(In fact, Go source files are defined to be encoded in UTF-8.) +<p> +The comment convention is the same as in C++: +<p> +<pre> +/* ... */ +// ... +</pre> +<p> +Later we'll have much more to say about printing. +<p> +<h2>Semicolons</h2> +<p> +You might have noticed that our program has no semicolons. In Go +code, the only place you typically see semicolons is separating the +clauses of <code>for</code> loops and the like; they are not necessary after +every statement. +<p> +In fact, what happens is that the formal language uses semicolons, +much as in C or Java, but they are inserted automatically +at the end of every line that looks like the end of a statement. You +don't need to type them yourself. +<p> +For details about how this is done you can see the language +specification, but in practice all you need to know is that you +never need to put a semicolon at the end of a line. (You can put +them in if you want to write multiple statements per line.) As an +extra help, you can also leave out a semicolon immediately before +a closing brace. +<p> +This approach makes for clean-looking, semicolon-free code. The +one surprise is that it's important to put the opening +brace of a construct such as an <code>if</code> statement on the same line as +the <code>if</code>; if you don't, there are situations that may not compile +or may give the wrong result. The language forces the brace style +to some extent. +<p> +<h2>Compiling</h2> +<p> +Go is a compiled language. At the moment there are two compilers. +<code>Gccgo</code> is a Go compiler that uses the GCC back end. There is also a +suite of compilers with different (and odd) names for each architecture: +<code>6g</code> for the 64-bit x86, <code>8g</code> for the 32-bit x86, and more. These +compilers run significantly faster but generate less efficient code +than <code>gccgo</code>. At the time of writing (late 2009), they also have +a more robust run-time system although <code>gccgo</code> is catching up. +<p> +Here's how to compile and run our program. With <code>6g</code>, say, +<p> +<pre> +$ 6g helloworld.go # compile; object goes into helloworld.6 +$ 6l helloworld.6 # link; output goes into 6.out +$ 6.out +Hello, world; or Καλημέρα κόσμε; or こんにちは 世界 +$ +</pre> +<p> +With <code>gccgo</code> it looks a little more traditional. +<p> +<pre> +$ gccgo helloworld.go +$ a.out +Hello, world; or Καλημέρα κόσμε; or こんにちは 世界 +$ +</pre> +<p> +<h2>Echo</h2> +<p> +Next up, here's a version of the Unix utility <code>echo(1)</code>: +<p> +<pre><!--{{code "progs/echo.go" `/package/` "$"}} +-->package main + +import ( + "os" + "flag" // command line option parser +) + +var omitNewline = flag.Bool("n", false, "don't print final newline") + +const ( + Space = " " + Newline = "\n" +) + +func main() { + flag.Parse() // Scans the arg list and sets up flags + var s string = "" + for i := 0; i < flag.NArg(); i++ { + if i > 0 { + s += Space + } + s += flag.Arg(i) + } + if !*omitNewline { + s += Newline + } + os.Stdout.WriteString(s) +} +</pre> +<p> +This program is small but it's doing a number of new things. In the last example, +we saw <code>func</code> introduce a function. The keywords <code>var</code>, <code>const</code>, and <code>type</code> +(not used yet) also introduce declarations, as does <code>import</code>. +Notice that we can group declarations of the same sort into +parenthesized lists, one item per line, as in the <code>import</code> and <code>const</code> clauses here. +But it's not necessary to do so; we could have said +<p> +<pre> +const Space = " " +const Newline = "\n" +</pre> +<p> +This program imports the <code>"os"</code> package to access its <code>Stdout</code> variable, of type +<code>*os.File</code>. The <code>import</code> statement is actually a declaration: in its general form, +as used in our ``hello world'' program, +it names the identifier (<code>fmt</code>) +that will be used to access members of the package imported from the file (<code>"fmt"</code>), +found in the current directory or in a standard location. +In this program, though, we've dropped the explicit name from the imports; by default, +packages are imported using the name defined by the imported package, +which by convention is of course the file name itself. Our ``hello world'' program +could have said just <code>import "fmt"</code>. +<p> +You can specify your +own import names if you want but it's only necessary if you need to resolve +a naming conflict. +<p> +Given <code>os.Stdout</code> we can use its <code>WriteString</code> method to print the string. +<p> +After importing the <code>flag</code> package, we use a <code>var</code> declaration +to create and initialize a global variable, called <code>omitNewline</code>, +to hold the value of echo's <code>-n</code> flag. +The variable has type <code>*bool</code>, pointer to <code>bool</code>. +<p> +In <code>main.main</code>, we parse the arguments (the call to <code>flag.Parse</code>) and then create a local +string variable with which to build the output. +<p> +The declaration statement has the form +<p> +<pre> +var s string = "" +</pre> +<p> +This is the <code>var</code> keyword, followed by the name of the variable, followed by +its type, followed by an equals sign and an initial value for the variable. +<p> +Go tries to be terse, and this declaration could be shortened. Since the +string constant is of type string, we don't have to tell the compiler that. +We could write +<p> +<pre> +var s = "" +</pre> +<p> +or we could go even shorter and write the idiom +<p> +<pre> +s := "" +</pre> +<p> +The <code>:=</code> operator is used a lot in Go to represent an initializing declaration. +There's one in the <code>for</code> clause on the next line: +<p> +<pre><!--{{code "progs/echo.go" `/for/`}} +--> for i := 0; i < flag.NArg(); i++ { +</pre> +<p> +The <code>flag</code> package has parsed the arguments and left the non-flag arguments +in a list that can be iterated over in the obvious way. +<p> +The Go <code>for</code> statement differs from that of C in a number of ways. First, +it's the only looping construct; there is no <code>while</code> or <code>do</code>. Second, +there are no parentheses on the clause, but the braces on the body +are mandatory. The same applies to the <code>if</code> and <code>switch</code> statements. +Later examples will show some other ways <code>for</code> can be written. +<p> +The body of the loop builds up the string <code>s</code> by appending (using <code>+=</code>) +the arguments and separating spaces. After the loop, if the <code>-n</code> flag is not +set, the program appends a newline. Finally, it writes the result. +<p> +Notice that <code>main.main</code> is a niladic function with no return type. +It's defined that way. Falling off the end of <code>main.main</code> means +''success''; if you want to signal an erroneous return, call +<p> +<pre> +os.Exit(1) +</pre> +<p> +The <code>os</code> package contains other essentials for getting +started; for instance, <code>os.Args</code> is a slice used by the +<code>flag</code> package to access the command-line arguments. +<p> +<h2>An Interlude about Types</h2> +<p> +Go has some familiar types such as <code>int</code> and <code>uint</code> (unsigned <code>int</code>), which represent +values of the ''appropriate'' size for the machine. It also defines +explicitly-sized types such as <code>int8</code>, <code>float64</code>, and so on, plus +unsigned integer types such as <code>uint</code>, <code>uint32</code>, etc. +These are distinct types; even if <code>int</code> and <code>int32</code> are both 32 bits in size, +they are not the same type. There is also a <code>byte</code> synonym for +<code>uint8</code>, which is the element type for strings. +<p> +Floating-point types are always sized: <code>float32</code> and <code>float64</code>, +plus <code>complex64</code> (two <code>float32s</code>) and <code>complex128</code> +(two <code>float64s</code>). Complex numbers are outside the +scope of this tutorial. +<p> +Speaking of <code>string</code>, that's a built-in type as well. Strings are +<i>immutable values</i>—they are not just arrays of <code>byte</code> values. +Once you've built a string <i>value</i>, you can't change it, although +of course you can change a string <i>variable</i> simply by +reassigning it. This snippet from <code>strings.go</code> is legal code: +<p> +<pre><!--{{code "progs/strings.go" `/hello/` `/ciao/`}} +--> s := "hello" + if s[1] != 'e' { + os.Exit(1) + } + s = "good bye" + var p *string = &s + *p = "ciao" +</pre> +<p> +However the following statements are illegal because they would modify +a <code>string</code> value: +<p> +<pre> +s[0] = 'x' +(*p)[1] = 'y' +</pre> +<p> +In C++ terms, Go strings are a bit like <code>const strings</code>, while pointers +to strings are analogous to <code>const string</code> references. +<p> +Yes, there are pointers. However, Go simplifies their use a little; +read on. +<p> +Arrays are declared like this: +<p> +<pre> +var arrayOfInt [10]int +</pre> +<p> +Arrays, like strings, are values, but they are mutable. This differs +from C, in which <code>arrayOfInt</code> would be usable as a pointer to <code>int</code>. +In Go, since arrays are values, it's meaningful (and useful) to talk +about pointers to arrays. +<p> +The size of the array is part of its type; however, one can declare +a <i>slice</i> variable to hold a reference to any array, of any size, +with the same element type. +A <i>slice +expression</i> has the form <code>a[low : high]</code>, representing +the internal array indexed from <code>low</code> through <code>high-1</code>; the resulting +slice is indexed from <code>0</code> through <code>high-low-1</code>. +In short, slices look a lot like arrays but with +no explicit size (<code>[]</code> vs. <code>[10]</code>) and they reference a segment of +an underlying, usually anonymous, regular array. Multiple slices +can share data if they represent pieces of the same array; +multiple arrays can never share data. +<p> +Slices are much more common in Go programs than +regular arrays; they're more flexible, have reference semantics, +and are efficient. What they lack is the precise control of storage +layout of a regular array; if you want to have a hundred elements +of an array stored within your structure, you should use a regular +array. To create one, use a compound value <i>constructor</i>—an +expression formed +from a type followed by a brace-bounded expression like this: +<p> +<pre> +[3]int{1,2,3} +</pre> +<p> +In this case the constructor builds an array of 3 <code>ints</code>. +<p> +When passing an array to a function, you almost always want +to declare the formal parameter to be a slice. When you call +the function, slice the array to create +(efficiently) a slice reference and pass that. +By default, the lower and upper bounds of a slice match the +ends of the existing object, so the concise notation <code>[:]</code> +will slice the whole array. +<p> +Using slices one can write this function (from <code>sum.go</code>): +<p> +<pre><!--{{code "progs/sum.go" `/sum/` `/^}/`}} +-->func sum(a []int) int { // returns an int + s := 0 + for i := 0; i < len(a); i++ { + s += a[i] + } + return s +} +</pre> +<p> +Note how the return type (<code>int</code>) is defined for <code>sum</code> by stating it +after the parameter list. +<p> +To call the function, we slice the array. This intricate call (we'll show +a simpler way in a moment) constructs +an array and slices it: +<p> +<pre> +s := sum([3]int{1,2,3}[:]) +</pre> +<p> +If you are creating a regular array but want the compiler to count the +elements for you, use <code>...</code> as the array size: +<p> +<pre> +s := sum([...]int{1,2,3}[:]) +</pre> +<p> +That's fussier than necessary, though. +In practice, unless you're meticulous about storage layout within a +data structure, a slice itself—using empty brackets with no size—is all you need: +<p> +<pre> +s := sum([]int{1,2,3}) +</pre> +<p> +There are also maps, which you can initialize like this: +<p> +<pre> +m := map[string]int{"one":1 , "two":2} +</pre> +<p> +The built-in function <code>len</code>, which returns number of elements, +makes its first appearance in <code>sum</code>. It works on strings, arrays, +slices, maps, and channels. +<p> +By the way, another thing that works on strings, arrays, slices, maps +and channels is the <code>range</code> clause on <code>for</code> loops. Instead of writing +<p> +<pre> +for i := 0; i < len(a); i++ { ... } +</pre> +<p> +to loop over the elements of a slice (or map or ...) , we could write +<p> +<pre> +for i, v := range a { ... } +</pre> +<p> +This assigns <code>i</code> to the index and <code>v</code> to the value of the successive +elements of the target of the range. See +<a href='/doc/effective_go.html'>Effective Go</a> +for more examples of its use. +<p> +<p> +<h2>An Interlude about Allocation</h2> +<p> +Most types in Go are values. If you have an <code>int</code> or a <code>struct</code> +or an array, assignment +copies the contents of the object. +To allocate a new variable, use the built-in function <code>new</code>, which +returns a pointer to the allocated storage. +<p> +<pre> +type T struct { a, b int } +var t *T = new(T) +</pre> +<p> +or the more idiomatic +<p> +<pre> +t := new(T) +</pre> +<p> +Some types—maps, slices, and channels (see below)—have reference semantics. +If you're holding a slice or a map and you modify its contents, other variables +referencing the same underlying data will see the modification. For these three +types you want to use the built-in function <code>make</code>: +<p> +<pre> +m := make(map[string]int) +</pre> +<p> +This statement initializes a new map ready to store entries. +If you just declare the map, as in +<p> +<pre> +var m map[string]int +</pre> +<p> +it creates a <code>nil</code> reference that cannot hold anything. To use the map, +you must first initialize the reference using <code>make</code> or by assignment from an +existing map. +<p> +Note that <code>new(T)</code> returns type <code>*T</code> while <code>make(T)</code> returns type +<code>T</code>. If you (mistakenly) allocate a reference object with <code>new</code> rather than <code>make</code>, +you receive a pointer to a nil reference, equivalent to +declaring an uninitialized variable and taking its address. +<p> +<h2>An Interlude about Constants</h2> +<p> +Although integers come in lots of sizes in Go, integer constants do not. +There are no constants like <code>0LL</code> or <code>0x0UL</code>. Instead, integer +constants are evaluated as large-precision values that +can overflow only when they are assigned to an integer variable with +too little precision to represent the value. +<p> +<pre> +const hardEight = (1 << 100) >> 97 // legal +</pre> +<p> +There are nuances that deserve redirection to the legalese of the +language specification but here are some illustrative examples: +<p> +<pre> +var a uint64 = 0 // a has type uint64, value 0 +a := uint64(0) // equivalent; uses a "conversion" +i := 0x1234 // i gets default type: int +var j int = 1e6 // legal - 1000000 is representable in an int +x := 1.5 // a float64, the default type for floating constants +i3div2 := 3/2 // integer division - result is 1 +f3div2 := 3./2. // floating-point division - result is 1.5 +</pre> +<p> +Conversions only work for simple cases such as converting <code>ints</code> of one +sign or size to another and between integers and floating-point numbers, +plus a couple of other instances outside the scope of a tutorial. +There are no automatic numeric conversions of any kind in Go, +other than that of making constants have concrete size and type when +assigned to a variable. +<p> +<h2>An I/O Package</h2> +<p> +Next we'll look at a simple package for doing file I/O with an +open/close/read/write interface. Here's the start of <code>file.go</code>: +<p> +<pre><!--{{code "progs/file.go" `/package/` `/^}/`}} +-->package file + +import ( + "os" + "syscall" +) + +type File struct { + fd int // file descriptor number + name string // file name at Open time +} +</pre> +<p> +The first few lines declare the name of the +package—<code>file</code>—and then import two packages. The <code>os</code> +package hides the differences +between various operating systems to give a consistent view of files and +so on; here we're going to use its error handling utilities +and reproduce the rudiments of its file I/O. +<p> +The other item is the low-level, external <code>syscall</code> package, which provides +a primitive interface to the underlying operating system's calls. +<p> +Next is a type definition: the <code>type</code> keyword introduces a type declaration, +in this case a data structure called <code>File</code>. +To make things a little more interesting, our <code>File</code> includes the name of the file +that the file descriptor refers to. +<p> +Because <code>File</code> starts with a capital letter, the type is available outside the package, +that is, by users of the package. In Go the rule about visibility of information is +simple: if a name (of a top-level type, function, method, constant or variable, or of +a structure field or method) is capitalized, users of the package may see it. Otherwise, the +name and hence the thing being named is visible only inside the package in which +it is declared. This is more than a convention; the rule is enforced by the compiler. +In Go, the term for publicly visible names is ''exported''. +<p> +In the case of <code>File</code>, all its fields are lower case and so invisible to users, but we +will soon give it some exported, upper-case methods. +<p> +First, though, here is a factory to create a <code>File</code>: +<p> +<pre><!--{{code "progs/file.go" `/newFile/` `/^}/`}} +-->func newFile(fd int, name string) *File { + if fd < 0 { + return nil + } + return &File{fd, name} +} +</pre> +<p> +This returns a pointer to a new <code>File</code> structure with the file descriptor and name +filled in. This code uses Go's notion of a ''composite literal'', analogous to +the ones used to build maps and arrays, to construct a new heap-allocated +object. We could write +<p> +<pre> +n := new(File) +n.fd = fd +n.name = name +return n +</pre> +<p> +but for simple structures like <code>File</code> it's easier to return the address of a +composite literal, as is done here in the <code>return</code> statement from <code>newFile</code>. +<p> +We can use the factory to construct some familiar, exported variables of type <code>*File</code>: +<p> +<pre><!--{{code "progs/file.go" `/var/` `/^.$/`}} +-->var ( + Stdin = newFile(syscall.Stdin, "/dev/stdin") + Stdout = newFile(syscall.Stdout, "/dev/stdout") + Stderr = newFile(syscall.Stderr, "/dev/stderr") +) + +</pre> +<p> +The <code>newFile</code> function was not exported because it's internal. The proper, +exported factory to use is <code>OpenFile</code> (we'll explain that name in a moment): +<p> +<pre><!--{{code "progs/file.go" `/func.OpenFile/` `/^}/`}} +-->func OpenFile(name string, mode int, perm uint32) (file *File, err os.Error) { + r, e := syscall.Open(name, mode, perm) + if e != 0 { + err = os.Errno(e) + } + return newFile(r, name), err +} +</pre> +<p> +There are a number of new things in these few lines. First, <code>OpenFile</code> returns +multiple values, a <code>File</code> and an error (more about errors in a moment). +We declare the +multi-value return as a parenthesized list of declarations; syntactically +they look just like a second parameter list. The function +<code>syscall.Open</code> +also has a multi-value return, which we can grab with the multi-variable +declaration on the first line; it declares <code>r</code> and <code>e</code> to hold the two values, +both of type <code>int</code> (although you'd have to look at the <code>syscall</code> package +to see that). Finally, <code>OpenFile</code> returns two values: a pointer to the new <code>File</code> +and the error. If <code>syscall.Open</code> fails, the file descriptor <code>r</code> will +be negative and <code>newFile</code> will return <code>nil</code>. +<p> +About those errors: The <code>os</code> library includes a general notion of an error. +It's a good idea to use its facility in your own interfaces, as we do here, for +consistent error handling throughout Go code. In <code>Open</code> we use a +conversion to translate Unix's integer <code>errno</code> value into the integer type +<code>os.Errno</code>, which implements <code>os.Error</code>. +<p> +Why <code>OpenFile</code> and not <code>Open</code>? To mimic Go's <code>os</code> package, which +our exercise is emulating. The <code>os</code> package takes the opportunity +to make the two commonest cases - open for read and create for +write - the simplest, just <code>Open</code> and <code>Create</code>. <code>OpenFile</code> is the +general case, analogous to the Unix system call <code>Open</code>. Here is +the implementation of our <code>Open</code> and <code>Create</code>; they're trivial +wrappers that eliminate common errors by capturing +the tricky standard arguments to open and, especially, to create a file: +<p> +<pre><!--{{code "progs/file.go" `/^const/` `/^}/`}} +-->const ( + O_RDONLY = syscall.O_RDONLY + O_RDWR = syscall.O_RDWR + O_CREATE = syscall.O_CREAT + O_TRUNC = syscall.O_TRUNC +) + +func Open(name string) (file *File, err os.Error) { + return OpenFile(name, O_RDONLY, 0) +} +</pre> +<p> +<pre><!--{{code "progs/file.go" `/func.Create/` `/^}/`}} +-->func Create(name string) (file *File, err os.Error) { + return OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0666) +} +</pre> +<p> +Back to our main story. +Now that we can build <code>Files</code>, we can write methods for them. To declare +a method of a type, we define a function to have an explicit receiver +of that type, placed +in parentheses before the function name. Here are some methods for <code>*File</code>, +each of which declares a receiver variable <code>file</code>. +<p> +<pre><!--{{code "progs/file.go" `/Close/` "$"}} +-->func (file *File) Close() os.Error { + if file == nil { + return os.EINVAL + } + e := syscall.Close(file.fd) + file.fd = -1 // so it can't be closed again + if e != 0 { + return os.Errno(e) + } + return nil +} + +func (file *File) Read(b []byte) (ret int, err os.Error) { + if file == nil { + return -1, os.EINVAL + } + r, e := syscall.Read(file.fd, b) + if e != 0 { + err = os.Errno(e) + } + return int(r), err +} + +func (file *File) Write(b []byte) (ret int, err os.Error) { + if file == nil { + return -1, os.EINVAL + } + r, e := syscall.Write(file.fd, b) + if e != 0 { + err = os.Errno(e) + } + return int(r), err +} + +func (file *File) String() string { + return file.name +} +</pre> +<p> +There is no implicit <code>this</code> and the receiver variable must be used to access +members of the structure. Methods are not declared within +the <code>struct</code> declaration itself. The <code>struct</code> declaration defines only data members. +In fact, methods can be created for almost any type you name, such as an integer or +array, not just for <code>structs</code>. We'll see an example with arrays later. +<p> +The <code>String</code> method is so called because of a printing convention we'll +describe later. +<p> +The methods use the public variable <code>os.EINVAL</code> to return the (<code>os.Error</code> +version of the) Unix error code <code>EINVAL</code>. The <code>os</code> library defines a standard +set of such error values. +<p> +We can now use our new package: +<p> +<pre><!--{{code "progs/helloworld3.go" `/package/` "$"}} +-->package main + +import ( + "./file" + "fmt" + "os" +) + +func main() { + hello := []byte("hello, world\n") + file.Stdout.Write(hello) + f, err := file.Open("/does/not/exist") + if f == nil { + fmt.Printf("can't open file; err=%s\n", err.String()) + os.Exit(1) + } +} +</pre> +<p> +The ''<code>./</code>'' in the import of ''<code>./file</code>'' tells the compiler +to use our own package rather than +something from the directory of installed packages. +(Also, ''<code>file.go</code>'' must be compiled before we can import the +package.) +<p> +Now we can compile and run the program. On Unix, this would be the result: +<p> +<pre> +$ 6g file.go # compile file package +$ 6g helloworld3.go # compile main package +$ 6l -o helloworld3 helloworld3.6 # link - no need to mention "file" +$ helloworld3 +hello, world +can't open file; err=No such file or directory +$ +</pre> +<p> +<h2>Rotting cats</h2> +<p> +Building on the <code>file</code> package, here's a simple version of the Unix utility <code>cat(1)</code>, +<code>progs/cat.go</code>: +<p> +<pre><!--{{code "progs/cat.go" `/package/` "$"}} +-->package main + +import ( + "./file" + "flag" + "fmt" + "os" +) + +func cat(f *file.File) { + const NBUF = 512 + var buf [NBUF]byte + for { + switch nr, er := f.Read(buf[:]); true { + case nr < 0: + fmt.Fprintf(os.Stderr, "cat: error reading from %s: %s\n", f.String(), er.String()) + os.Exit(1) + case nr == 0: // EOF + return + case nr > 0: + if nw, ew := file.Stdout.Write(buf[0:nr]); nw != nr { + fmt.Fprintf(os.Stderr, "cat: error writing from %s: %s\n", f.String(), ew.String()) + os.Exit(1) + } + } + } +} + +func main() { + flag.Parse() // Scans the arg list and sets up flags + if flag.NArg() == 0 { + cat(file.Stdin) + } + for i := 0; i < flag.NArg(); i++ { + f, err := file.Open(flag.Arg(i)) + if f == nil { + fmt.Fprintf(os.Stderr, "cat: can't open %s: error %s\n", flag.Arg(i), err) + os.Exit(1) + } + cat(f) + f.Close() + } +} +</pre> +<p> +By now this should be easy to follow, but the <code>switch</code> statement introduces some +new features. Like a <code>for</code> loop, an <code>if</code> or <code>switch</code> can include an +initialization statement. The <code>switch</code> statement in <code>cat</code> uses one to create variables +<code>nr</code> and <code>er</code> to hold the return values from the call to <code>f.Read</code>. (The <code>if</code> a few lines later +has the same idea.) The <code>switch</code> statement is general: it evaluates the cases +from top to bottom looking for the first case that matches the value; the +case expressions don't need to be constants or even integers, as long as +they all have the same type. +<p> +Since the <code>switch</code> value is just <code>true</code>, we could leave it off—as is also +the situation +in a <code>for</code> statement, a missing value means <code>true</code>. In fact, such a <code>switch</code> +is a form of <code>if-else</code> chain. While we're here, it should be mentioned that in +<code>switch</code> statements each <code>case</code> has an implicit <code>break</code>. +<p> +The argument to <code>file.Stdout.Write</code> is created by slicing the array <code>buf</code>. +Slices provide the standard Go way to handle I/O buffers. +<p> +Now let's make a variant of <code>cat</code> that optionally does <code>rot13</code> on its input. +It's easy to do by just processing the bytes, but instead we will exploit +Go's notion of an <i>interface</i>. +<p> +The <code>cat</code> subroutine uses only two methods of <code>f</code>: <code>Read</code> and <code>String</code>, +so let's start by defining an interface that has exactly those two methods. +Here is code from <code>progs/cat_rot13.go</code>: +<p> +<pre><!--{{code "progs/cat_rot13.go" `/type.reader/` `/^}/`}} +-->type reader interface { + Read(b []byte) (ret int, err os.Error) + String() string +} +</pre> +<p> +Any type that has the two methods of <code>reader</code>—regardless of whatever +other methods the type may also have—is said to <i>implement</i> the +interface. Since <code>file.File</code> implements these methods, it implements the +<code>reader</code> interface. We could tweak the <code>cat</code> subroutine to accept a <code>reader</code> +instead of a <code>*file.File</code> and it would work just fine, but let's embellish a little +first by writing a second type that implements <code>reader</code>, one that wraps an +existing <code>reader</code> and does <code>rot13</code> on the data. To do this, we just define +the type and implement the methods and with no other bookkeeping, +we have a second implementation of the <code>reader</code> interface. +<p> +<pre><!--{{code "progs/cat_rot13.go" `/type.rotate13/` `/end.of.rotate13/`}} +-->type rotate13 struct { + source reader +} + +func newRotate13(source reader) *rotate13 { + return &rotate13{source} +} + +func (r13 *rotate13) Read(b []byte) (ret int, err os.Error) { + r, e := r13.source.Read(b) + for i := 0; i < r; i++ { + b[i] = rot13(b[i]) + } + return r, e +} + +func (r13 *rotate13) String() string { + return r13.source.String() +} +// end of rotate13 implementation +</pre> +<p> +(The <code>rot13</code> function called in <code>Read</code> is trivial and not worth reproducing here.) +<p> +To use the new feature, we define a flag: +<p> +<pre><!--{{code "progs/cat_rot13.go" `/rot13Flag/`}} +-->var rot13Flag = flag.Bool("rot13", false, "rot13 the input") +</pre> +<p> +and use it from within a mostly unchanged <code>cat</code> function: +<p> +<pre><!--{{code "progs/cat_rot13.go" `/func.cat/` `/^}/`}} +-->func cat(r reader) { + const NBUF = 512 + var buf [NBUF]byte + + if *rot13Flag { + r = newRotate13(r) + } + for { + switch nr, er := r.Read(buf[:]); { + case nr < 0: + fmt.Fprintf(os.Stderr, "cat: error reading from %s: %s\n", r.String(), er.String()) + os.Exit(1) + case nr == 0: // EOF + return + case nr > 0: + nw, ew := file.Stdout.Write(buf[0:nr]) + if nw != nr { + fmt.Fprintf(os.Stderr, "cat: error writing from %s: %s\n", r.String(), ew.String()) + os.Exit(1) + } + } + } +} +</pre> +<p> +(We could also do the wrapping in <code>main</code> and leave <code>cat</code> mostly alone, except +for changing the type of the argument; consider that an exercise.) +The <code>if</code> at the top of <code>cat</code> sets it all up: If the <code>rot13</code> flag is true, wrap the <code>reader</code> +we received into a <code>rotate13</code> and proceed. Note that the interface variables +are values, not pointers: the argument is of type <code>reader</code>, not <code>*reader</code>, +even though under the covers it holds a pointer to a <code>struct</code>. +<p> +Here it is in action: +<p> +<pre> +$ echo abcdefghijklmnopqrstuvwxyz | ./cat +abcdefghijklmnopqrstuvwxyz +$ echo abcdefghijklmnopqrstuvwxyz | ./cat --rot13 +nopqrstuvwxyzabcdefghijklm +$ +</pre> +<p> +Fans of dependency injection may take cheer from how easily interfaces +allow us to substitute the implementation of a file descriptor. +<p> +Interfaces are a distinctive feature of Go. An interface is implemented by a +type if the type implements all the methods declared in the interface. +This means +that a type may implement an arbitrary number of different interfaces. +There is no type hierarchy; things can be much more <i>ad hoc</i>, +as we saw with <code>rot13</code>. The type <code>file.File</code> implements <code>reader</code>; it could also +implement a <code>writer</code>, or any other interface built from its methods that +fits the current situation. Consider the <i>empty interface</i> +<p> +<pre> +type Empty interface {} +</pre> +<p> +<i>Every</i> type implements the empty interface, which makes it +useful for things like containers. +<p> +<h2>Sorting</h2> +<p> +Interfaces provide a simple form of polymorphism. They completely +separate the definition of what an object does from how it does it, allowing +distinct implementations to be represented at different times by the +same interface variable. +<p> +As an example, consider this simple sort algorithm taken from <code>progs/sort.go</code>: +<p> +<pre><!--{{code "progs/sort.go" `/func.Sort/` `/^}/`}} +-->func Sort(data Interface) { + for i := 1; i < data.Len(); i++ { + for j := i; j > 0 && data.Less(j, j-1); j-- { + data.Swap(j, j-1) + } + } +} +</pre> +<p> +The code needs only three methods, which we wrap into sort's <code>Interface</code>: +<p> +<pre><!--{{code "progs/sort.go" `/interface/` `/^}/`}} +-->type Interface interface { + Len() int + Less(i, j int) bool + Swap(i, j int) +} +</pre> +<p> +We can apply <code>Sort</code> to any type that implements <code>Len</code>, <code>Less</code>, and <code>Swap</code>. +The <code>sort</code> package includes the necessary methods to allow sorting of +arrays of integers, strings, etc.; here's the code for arrays of <code>int</code> +<p> +<pre><!--{{code "progs/sort.go" `/type.*IntSlice/` `/Swap/`}} +-->type IntSlice []int + +func (p IntSlice) Len() int { return len(p) } +func (p IntSlice) Less(i, j int) bool { return p[i] < p[j] } +func (p IntSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } +</pre> +<p> +Here we see methods defined for non-<code>struct</code> types. You can define methods +for any type you define and name in your package. +<p> +And now a routine to test it out, from <code>progs/sortmain.go</code>. This +uses a function in the <code>sort</code> package, omitted here for brevity, +to test that the result is sorted. +<p> +<pre><!--{{code "progs/sortmain.go" `/func.ints/` `/^}/`}} +-->func ints() { + data := []int{74, 59, 238, -784, 9845, 959, 905, 0, 0, 42, 7586, -5467984, 7586} + a := sort.IntSlice(data) + sort.Sort(a) + if !sort.IsSorted(a) { + panic("fail") + } +} +</pre> +<p> +If we have a new type we want to be able to sort, all we need to do is +to implement the three methods for that type, like this: +<p> +<pre><!--{{code "progs/sortmain.go" `/type.day/` `/Swap/`}} +-->type day struct { + num int + shortName string + longName string +} + +type dayArray struct { + data []*day +} + +func (p *dayArray) Len() int { return len(p.data) } +func (p *dayArray) Less(i, j int) bool { return p.data[i].num < p.data[j].num } +func (p *dayArray) Swap(i, j int) { p.data[i], p.data[j] = p.data[j], p.data[i] } +</pre> +<p> +<p> +<h2>Printing</h2> +<p> +The examples of formatted printing so far have been modest. In this section +we'll talk about how formatted I/O can be done well in Go. +<p> +We've seen simple uses of the package <code>fmt</code>, which +implements <code>Printf</code>, <code>Fprintf</code>, and so on. +Within the <code>fmt</code> package, <code>Printf</code> is declared with this signature: +<p> +<pre> +Printf(format string, v ...interface{}) (n int, errno os.Error) +</pre> +<p> +The token <code>...</code> introduces a variable-length argument list that in C would +be handled using the <code>stdarg.h</code> macros. +In Go, variadic functions are passed a slice of the arguments of the +specified type. In <code>Printf</code>'s case, the declaration says <code>...interface{}</code> +so the actual type is a slice of empty interface values, <code>[]interface{}</code>. +<code>Printf</code> can examine the arguments by iterating over the slice +and, for each element, using a type switch or the reflection library +to interpret the value. +It's off topic here but such run-time type analysis +helps explain some of the nice properties of Go's <code>Printf</code>, +due to the ability of <code>Printf</code> to discover the type of its arguments +dynamically. +<p> +For example, in C each format must correspond to the type of its +argument. It's easier in many cases in Go. Instead of <code>%llud</code> you +can just say <code>%d</code>; <code>Printf</code> knows the size and signedness of the +integer and can do the right thing for you. The snippet +<p> +<pre><!--{{code "progs/print.go" 10 11}} +--> var u64 uint64 = 1<<64 - 1 + fmt.Printf("%d %d\n", u64, int64(u64)) +</pre> +<p> +prints +<p> +<pre> +18446744073709551615 -1 +</pre> +<p> +In fact, if you're lazy the format <code>%v</code> will print, in a simple +appropriate style, any value, even an array or structure. The output of +<p> +<pre><!--{{code "progs/print.go" 14 20}} +--> type T struct { + a int + b string + } + t := T{77, "Sunset Strip"} + a := []int{1, 2, 3, 4} + fmt.Printf("%v %v %v\n", u64, t, a) +</pre> +<p> +is +<p> +<pre> +18446744073709551615 {77 Sunset Strip} [1 2 3 4] +</pre> +<p> +You can drop the formatting altogether if you use <code>Print</code> or <code>Println</code> +instead of <code>Printf</code>. Those routines do fully automatic formatting. +The <code>Print</code> function just prints its elements out using the equivalent +of <code>%v</code> while <code>Println</code> inserts spaces between arguments +and adds a newline. The output of each of these two lines is identical +to that of the <code>Printf</code> call above. +<p> +<pre><!--{{code "progs/print.go" 21 22}} +--> fmt.Print(u64, " ", t, " ", a, "\n") + fmt.Println(u64, t, a) +</pre> +<p> +If you have your own type you'd like <code>Printf</code> or <code>Print</code> to format, +just give it a <code>String</code> method that returns a string. The print +routines will examine the value to inquire whether it implements +the method and if so, use it rather than some other formatting. +Here's a simple example. +<p> +<pre><!--{{code "progs/print_string.go" 9 "$"}} +-->type testType struct { + a int + b string +} + +func (t *testType) String() string { + return fmt.Sprint(t.a) + " " + t.b +} + +func main() { + t := &testType{77, "Sunset Strip"} + fmt.Println(t) +} +</pre> +<p> +Since <code>*testType</code> has a <code>String</code> method, the +default formatter for that type will use it and produce the output +<p> +<pre> +77 Sunset Strip +</pre> +<p> +Observe that the <code>String</code> method calls <code>Sprint</code> (the obvious Go +variant that returns a string) to do its formatting; special formatters +can use the <code>fmt</code> library recursively. +<p> +Another feature of <code>Printf</code> is that the format <code>%T</code> will print a string +representation of the type of a value, which can be handy when debugging +polymorphic code. +<p> +It's possible to write full custom print formats with flags and precisions +and such, but that's getting a little off the main thread so we'll leave it +as an exploration exercise. +<p> +You might ask, though, how <code>Printf</code> can tell whether a type implements +the <code>String</code> method. Actually what it does is ask if the value can +be converted to an interface variable that implements the method. +Schematically, given a value <code>v</code>, it does this: +<p> +<p> +<pre> +type Stringer interface { + String() string +} +</pre> +<p> +<pre> +s, ok := v.(Stringer) // Test whether v implements "String()" +if ok { + result = s.String() +} else { + result = defaultOutput(v) +} +</pre> +<p> +The code uses a ``type assertion'' (<code>v.(Stringer)</code>) to test if the value stored in +<code>v</code> satisfies the <code>Stringer</code> interface; if it does, <code>s</code> +will become an interface variable implementing the method and <code>ok</code> will +be <code>true</code>. We then use the interface variable to call the method. +(The ''comma, ok'' pattern is a Go idiom used to test the success of +operations such as type conversion, map update, communications, and so on, +although this is the only appearance in this tutorial.) +If the value does not satisfy the interface, <code>ok</code> will be false. +<p> +In this snippet the name <code>Stringer</code> follows the convention that we add ''[e]r'' +to interfaces describing simple method sets like this. +<p> +One last wrinkle. To complete the suite, besides <code>Printf</code> etc. and <code>Sprintf</code> +etc., there are also <code>Fprintf</code> etc. Unlike in C, <code>Fprintf</code>'s first argument is +not a file. Instead, it is a variable of type <code>io.Writer</code>, which is an +interface type defined in the <code>io</code> library: +<p> +<pre> +type Writer interface { + Write(p []byte) (n int, err os.Error) +} +</pre> +<p> +(This interface is another conventional name, this time for <code>Write</code>; there are also +<code>io.Reader</code>, <code>io.ReadWriter</code>, and so on.) +Thus you can call <code>Fprintf</code> on any type that implements a standard <code>Write</code> +method, not just files but also network channels, buffers, whatever +you want. +<p> +<h2>Prime numbers</h2> +<p> +Now we come to processes and communication—concurrent programming. +It's a big subject so to be brief we assume some familiarity with the topic. +<p> +A classic program in the style is a prime sieve. +(The sieve of Eratosthenes is computationally more efficient than +the algorithm presented here, but we are more interested in concurrency than +algorithmics at the moment.) +It works by taking a stream of all the natural numbers and introducing +a sequence of filters, one for each prime, to winnow the multiples of +that prime. At each step we have a sequence of filters of the primes +so far, and the next number to pop out is the next prime, which triggers +the creation of the next filter in the chain. +<p> +Here's a flow diagram; each box represents a filter element whose +creation is triggered by the first number that flowed from the +elements before it. +<p> +<br> +<p> + <img src='sieve.gif'> +<p> +<br> +<p> +To create a stream of integers, we use a Go <i>channel</i>, which, +borrowing from CSP's descendants, represents a communications +channel that can connect two concurrent computations. +In Go, channel variables are references to a run-time object that +coordinates the communication; as with maps and slices, use +<code>make</code> to create a new channel. +<p> +Here is the first function in <code>progs/sieve.go</code>: +<p> +<pre><!--{{code "progs/sieve.go" `/Send/` `/^}/`}} +-->// Send the sequence 2, 3, 4, ... to channel 'ch'. +func generate(ch chan int) { + for i := 2; ; i++ { + ch <- i // Send 'i' to channel 'ch'. + } +} +</pre> +<p> +The <code>generate</code> function sends the sequence 2, 3, 4, 5, ... to its +argument channel, <code>ch</code>, using the binary communications operator <code><-</code>. +Channel operations block, so if there's no recipient for the value on <code>ch</code>, +the send operation will wait until one becomes available. +<p> +The <code>filter</code> function has three arguments: an input channel, an output +channel, and a prime number. It copies values from the input to the +output, discarding anything divisible by the prime. The unary communications +operator <code><-</code> (receive) retrieves the next value on the channel. +<p> +<pre><!--{{code "progs/sieve.go" `/Copy.the/` `/^}/`}} +-->// Copy the values from channel 'in' to channel 'out', +// removing those divisible by 'prime'. +func filter(in, out chan int, prime int) { + for { + i := <-in // Receive value of new variable 'i' from 'in'. + if i%prime != 0 { + out <- i // Send 'i' to channel 'out'. + } + } +} +</pre> +<p> +The generator and filters execute concurrently. Go has +its own model of process/threads/light-weight processes/coroutines, +so to avoid notational confusion we call concurrently executing +computations in Go <i>goroutines</i>. To start a goroutine, +invoke the function, prefixing the call with the keyword <code>go</code>; +this starts the function running in parallel with the current +computation but in the same address space: +<p> +<pre> +go sum(hugeArray) // calculate sum in the background +</pre> +<p> +If you want to know when the calculation is done, pass a channel +on which it can report back: +<p> +<pre> +ch := make(chan int) +go sum(hugeArray, ch) +// ... do something else for a while +result := <-ch // wait for, and retrieve, result +</pre> +<p> +Back to our prime sieve. Here's how the sieve pipeline is stitched +together: +<p> +<pre><!--{{code "progs/sieve.go" `/func.main/` `/^}/`}} +-->func main() { + ch := make(chan int) // Create a new channel. + go generate(ch) // Start generate() as a goroutine. + for i := 0; i < 100; i++ { // Print the first hundred primes. + prime := <-ch + fmt.Println(prime) + ch1 := make(chan int) + go filter(ch, ch1, prime) + ch = ch1 + } +} +</pre> +<p> +The first line of <code>main</code> creates the initial channel to pass to <code>generate</code>, which it +then starts up. As each prime pops out of the channel, a new <code>filter</code> +is added to the pipeline and <i>its</i> output becomes the new value +of <code>ch</code>. +<p> +The sieve program can be tweaked to use a pattern common +in this style of programming. Here is a variant version +of <code>generate</code>, from <code>progs/sieve1.go</code>: +<p> +<pre><!--{{code "progs/sieve1.go" `/func.generate/` `/^}/`}} +-->func generate() chan int { + ch := make(chan int) + go func() { + for i := 2; ; i++ { + ch <- i + } + }() + return ch +} +</pre> +<p> +This version does all the setup internally. It creates the output +channel, launches a goroutine running a function literal, and +returns the channel to the caller. It is a factory for concurrent +execution, starting the goroutine and returning its connection. +<p> +The function literal notation used in the <code>go</code> statement allows us to construct an +anonymous function and invoke it on the spot. Notice that the local +variable <code>ch</code> is available to the function literal and lives on even +after <code>generate</code> returns. +<p> +The same change can be made to <code>filter</code>: +<p> +<pre><!--{{code "progs/sieve1.go" `/func.filter/` `/^}/`}} +-->func filter(in chan int, prime int) chan int { + out := make(chan int) + go func() { + for { + if i := <-in; i%prime != 0 { + out <- i + } + } + }() + return out +} +</pre> +<p> +The <code>sieve</code> function's main loop becomes simpler and clearer as a +result, and while we're at it let's turn it into a factory too: +<p> +<pre><!--{{code "progs/sieve1.go" `/func.sieve/` `/^}/`}} +-->func sieve() chan int { + out := make(chan int) + go func() { + ch := generate() + for { + prime := <-ch + out <- prime + ch = filter(ch, prime) + } + }() + return out +} +</pre> +<p> +Now <code>main</code>'s interface to the prime sieve is a channel of primes: +<p> +<pre><!--{{code "progs/sieve1.go" `/func.main/` `/^}/`}} +-->func main() { + primes := sieve() + for i := 0; i < 100; i++ { // Print the first hundred primes. + fmt.Println(<-primes) + } +} +</pre> +<p> +<h2>Multiplexing</h2> +<p> +With channels, it's possible to serve multiple independent client goroutines without +writing an explicit multiplexer. The trick is to send the server a channel in the message, +which it will then use to reply to the original sender. +A realistic client-server program is a lot of code, so here is a very simple substitute +to illustrate the idea. It starts by defining a <code>request</code> type, which embeds a channel +that will be used for the reply. +<p> +<pre><!--{{code "progs/server.go" `/type.request/` `/^}/`}} +-->type request struct { + a, b int + replyc chan int +} +</pre> +<p> +The server will be trivial: it will do simple binary operations on integers. Here's the +code that invokes the operation and responds to the request: +<p> +<pre><!--{{code "progs/server.go" `/type.binOp/` `/^}/`}} +-->type binOp func(a, b int) int + +func run(op binOp, req *request) { + reply := op(req.a, req.b) + req.replyc <- reply +} +</pre> +<p> +The type declaration makes <code>binOp</code> represent a function taking two integers and +returning a third. +<p> +The <code>server</code> routine loops forever, receiving requests and, to avoid blocking due to +a long-running operation, starting a goroutine to do the actual work. +<p> +<pre><!--{{code "progs/server.go" `/func.server/` `/^}/`}} +-->func server(op binOp, service chan *request) { + for { + req := <-service + go run(op, req) // don't wait for it + } +} +</pre> +<p> +We construct a server in a familiar way, starting it and returning a channel +connected to it: +<p> +<pre><!--{{code "progs/server.go" `/func.startServer/` `/^}/`}} +-->func startServer(op binOp) chan *request { + req := make(chan *request) + go server(op, req) + return req +} +</pre> +<p> +Here's a simple test. It starts a server with an addition operator and sends out +<code>N</code> requests without waiting for the replies. Only after all the requests are sent +does it check the results. +<p> +<pre><!--{{code "progs/server.go" `/func.main/` `/^}/`}} +-->func main() { + adder := startServer(func(a, b int) int { return a + b }) + const N = 100 + var reqs [N]request + for i := 0; i < N; i++ { + req := &reqs[i] + req.a = i + req.b = i + N + req.replyc = make(chan int) + adder <- req + } + for i := N - 1; i >= 0; i-- { // doesn't matter what order + if <-reqs[i].replyc != N+2*i { + fmt.Println("fail at", i) + } + } + fmt.Println("done") +} +</pre> +<p> +One annoyance with this program is that it doesn't shut down the server cleanly; when <code>main</code> returns +there are a number of lingering goroutines blocked on communication. To solve this, +we can provide a second, <code>quit</code> channel to the server: +<p> +<pre><!--{{code "progs/server1.go" `/func.startServer/` `/^}/`}} +-->func startServer(op binOp) (service chan *request, quit chan bool) { + service = make(chan *request) + quit = make(chan bool) + go server(op, service, quit) + return service, quit +} +</pre> +<p> +It passes the quit channel to the <code>server</code> function, which uses it like this: +<p> +<pre><!--{{code "progs/server1.go" `/func.server/` `/^}/`}} +-->func server(op binOp, service chan *request, quit chan bool) { + for { + select { + case req := <-service: + go run(op, req) // don't wait for it + case <-quit: + return + } + } +} +</pre> +<p> +Inside <code>server</code>, the <code>select</code> statement chooses which of the multiple communications +listed by its cases can proceed. If all are blocked, it waits until one can proceed; if +multiple can proceed, it chooses one at random. In this instance, the <code>select</code> allows +the server to honor requests until it receives a quit message, at which point it +returns, terminating its execution. +<p> +<p> +All that's left is to strobe the <code>quit</code> channel +at the end of main: +<p> +<pre><!--{{code "progs/server1.go" `/adder,.quit/`}} +--> adder, quit := startServer(func(a, b int) int { return a + b }) +</pre> +... +<pre><!--{{code "progs/server1.go" `/quit....true/`}} +--> quit <- true +</pre> +<p> +There's a lot more to Go programming and concurrent programming in general but this +quick tour should give you some of the basics. diff --git a/doc/go_tutorial.tmpl b/doc/go_tutorial.tmpl new file mode 100644 index 000000000..c170c25aa --- /dev/null +++ b/doc/go_tutorial.tmpl @@ -0,0 +1,990 @@ +<!-- A Tutorial for the Go Programming Language --> +<h2>Introduction</h2> +<p> +This document is a tutorial introduction to the basics of the Go programming +language, intended for programmers familiar with C or C++. It is not a comprehensive +guide to the language; at the moment the document closest to that is the +<a href='/doc/go_spec.html'>language specification</a>. +After you've read this tutorial, you should look at +<a href='/doc/effective_go.html'>Effective Go</a>, +which digs deeper into how the language is used and +talks about the style and idioms of programming in Go. +Also, slides from a 3-day course about Go are available. +They provide some background and a lot of examples: +<a href='/doc/GoCourseDay1.pdf'>Day 1</a>, +<a href='/doc/GoCourseDay2.pdf'>Day 2</a>, +<a href='/doc/GoCourseDay3.pdf'>Day 3</a>. +<p> +The presentation here proceeds through a series of modest programs to illustrate +key features of the language. All the programs work (at time of writing) and are +checked into the repository in the directory <a href='/doc/progs'><code>/doc/progs/</code></a>. +<p> +<h2>Hello, World</h2> +<p> +Let's start in the usual way: +<p> +{{code "progs/helloworld.go" `/package/` "$"}} +<p> +Every Go source file declares, using a <code>package</code> statement, which package it's part of. +It may also import other packages to use their facilities. +This program imports the package <code>fmt</code> to gain access to +our old, now capitalized and package-qualified, friend, <code>fmt.Printf</code>. +<p> +Functions are introduced with the <code>func</code> keyword. +The <code>main</code> package's <code>main</code> function is where the program starts running (after +any initialization). +<p> +String constants can contain Unicode characters, encoded in UTF-8. +(In fact, Go source files are defined to be encoded in UTF-8.) +<p> +The comment convention is the same as in C++: +<p> +<pre> +/* ... */ +// ... +</pre> +<p> +Later we'll have much more to say about printing. +<p> +<h2>Semicolons</h2> +<p> +You might have noticed that our program has no semicolons. In Go +code, the only place you typically see semicolons is separating the +clauses of <code>for</code> loops and the like; they are not necessary after +every statement. +<p> +In fact, what happens is that the formal language uses semicolons, +much as in C or Java, but they are inserted automatically +at the end of every line that looks like the end of a statement. You +don't need to type them yourself. +<p> +For details about how this is done you can see the language +specification, but in practice all you need to know is that you +never need to put a semicolon at the end of a line. (You can put +them in if you want to write multiple statements per line.) As an +extra help, you can also leave out a semicolon immediately before +a closing brace. +<p> +This approach makes for clean-looking, semicolon-free code. The +one surprise is that it's important to put the opening +brace of a construct such as an <code>if</code> statement on the same line as +the <code>if</code>; if you don't, there are situations that may not compile +or may give the wrong result. The language forces the brace style +to some extent. +<p> +<h2>Compiling</h2> +<p> +Go is a compiled language. At the moment there are two compilers. +<code>Gccgo</code> is a Go compiler that uses the GCC back end. There is also a +suite of compilers with different (and odd) names for each architecture: +<code>6g</code> for the 64-bit x86, <code>8g</code> for the 32-bit x86, and more. These +compilers run significantly faster but generate less efficient code +than <code>gccgo</code>. At the time of writing (late 2009), they also have +a more robust run-time system although <code>gccgo</code> is catching up. +<p> +Here's how to compile and run our program. With <code>6g</code>, say, +<p> +<pre> +$ 6g helloworld.go # compile; object goes into helloworld.6 +$ 6l helloworld.6 # link; output goes into 6.out +$ 6.out +Hello, world; or Καλημέρα κόσμε; or こんにちは 世界 +$ +</pre> +<p> +With <code>gccgo</code> it looks a little more traditional. +<p> +<pre> +$ gccgo helloworld.go +$ a.out +Hello, world; or Καλημέρα κόσμε; or こんにちは 世界 +$ +</pre> +<p> +<h2>Echo</h2> +<p> +Next up, here's a version of the Unix utility <code>echo(1)</code>: +<p> +{{code "progs/echo.go" `/package/` "$"}} +<p> +This program is small but it's doing a number of new things. In the last example, +we saw <code>func</code> introduce a function. The keywords <code>var</code>, <code>const</code>, and <code>type</code> +(not used yet) also introduce declarations, as does <code>import</code>. +Notice that we can group declarations of the same sort into +parenthesized lists, one item per line, as in the <code>import</code> and <code>const</code> clauses here. +But it's not necessary to do so; we could have said +<p> +<pre> +const Space = " " +const Newline = "\n" +</pre> +<p> +This program imports the <code>"os"</code> package to access its <code>Stdout</code> variable, of type +<code>*os.File</code>. The <code>import</code> statement is actually a declaration: in its general form, +as used in our ``hello world'' program, +it names the identifier (<code>fmt</code>) +that will be used to access members of the package imported from the file (<code>"fmt"</code>), +found in the current directory or in a standard location. +In this program, though, we've dropped the explicit name from the imports; by default, +packages are imported using the name defined by the imported package, +which by convention is of course the file name itself. Our ``hello world'' program +could have said just <code>import "fmt"</code>. +<p> +You can specify your +own import names if you want but it's only necessary if you need to resolve +a naming conflict. +<p> +Given <code>os.Stdout</code> we can use its <code>WriteString</code> method to print the string. +<p> +After importing the <code>flag</code> package, we use a <code>var</code> declaration +to create and initialize a global variable, called <code>omitNewline</code>, +to hold the value of echo's <code>-n</code> flag. +The variable has type <code>*bool</code>, pointer to <code>bool</code>. +<p> +In <code>main.main</code>, we parse the arguments (the call to <code>flag.Parse</code>) and then create a local +string variable with which to build the output. +<p> +The declaration statement has the form +<p> +<pre> +var s string = "" +</pre> +<p> +This is the <code>var</code> keyword, followed by the name of the variable, followed by +its type, followed by an equals sign and an initial value for the variable. +<p> +Go tries to be terse, and this declaration could be shortened. Since the +string constant is of type string, we don't have to tell the compiler that. +We could write +<p> +<pre> +var s = "" +</pre> +<p> +or we could go even shorter and write the idiom +<p> +<pre> +s := "" +</pre> +<p> +The <code>:=</code> operator is used a lot in Go to represent an initializing declaration. +There's one in the <code>for</code> clause on the next line: +<p> +{{code "progs/echo.go" `/for/`}} +<p> +The <code>flag</code> package has parsed the arguments and left the non-flag arguments +in a list that can be iterated over in the obvious way. +<p> +The Go <code>for</code> statement differs from that of C in a number of ways. First, +it's the only looping construct; there is no <code>while</code> or <code>do</code>. Second, +there are no parentheses on the clause, but the braces on the body +are mandatory. The same applies to the <code>if</code> and <code>switch</code> statements. +Later examples will show some other ways <code>for</code> can be written. +<p> +The body of the loop builds up the string <code>s</code> by appending (using <code>+=</code>) +the arguments and separating spaces. After the loop, if the <code>-n</code> flag is not +set, the program appends a newline. Finally, it writes the result. +<p> +Notice that <code>main.main</code> is a niladic function with no return type. +It's defined that way. Falling off the end of <code>main.main</code> means +''success''; if you want to signal an erroneous return, call +<p> +<pre> +os.Exit(1) +</pre> +<p> +The <code>os</code> package contains other essentials for getting +started; for instance, <code>os.Args</code> is a slice used by the +<code>flag</code> package to access the command-line arguments. +<p> +<h2>An Interlude about Types</h2> +<p> +Go has some familiar types such as <code>int</code> and <code>uint</code> (unsigned <code>int</code>), which represent +values of the ''appropriate'' size for the machine. It also defines +explicitly-sized types such as <code>int8</code>, <code>float64</code>, and so on, plus +unsigned integer types such as <code>uint</code>, <code>uint32</code>, etc. +These are distinct types; even if <code>int</code> and <code>int32</code> are both 32 bits in size, +they are not the same type. There is also a <code>byte</code> synonym for +<code>uint8</code>, which is the element type for strings. +<p> +Floating-point types are always sized: <code>float32</code> and <code>float64</code>, +plus <code>complex64</code> (two <code>float32s</code>) and <code>complex128</code> +(two <code>float64s</code>). Complex numbers are outside the +scope of this tutorial. +<p> +Speaking of <code>string</code>, that's a built-in type as well. Strings are +<i>immutable values</i>—they are not just arrays of <code>byte</code> values. +Once you've built a string <i>value</i>, you can't change it, although +of course you can change a string <i>variable</i> simply by +reassigning it. This snippet from <code>strings.go</code> is legal code: +<p> +{{code "progs/strings.go" `/hello/` `/ciao/`}} +<p> +However the following statements are illegal because they would modify +a <code>string</code> value: +<p> +<pre> +s[0] = 'x' +(*p)[1] = 'y' +</pre> +<p> +In C++ terms, Go strings are a bit like <code>const strings</code>, while pointers +to strings are analogous to <code>const string</code> references. +<p> +Yes, there are pointers. However, Go simplifies their use a little; +read on. +<p> +Arrays are declared like this: +<p> +<pre> +var arrayOfInt [10]int +</pre> +<p> +Arrays, like strings, are values, but they are mutable. This differs +from C, in which <code>arrayOfInt</code> would be usable as a pointer to <code>int</code>. +In Go, since arrays are values, it's meaningful (and useful) to talk +about pointers to arrays. +<p> +The size of the array is part of its type; however, one can declare +a <i>slice</i> variable to hold a reference to any array, of any size, +with the same element type. +A <i>slice +expression</i> has the form <code>a[low : high]</code>, representing +the internal array indexed from <code>low</code> through <code>high-1</code>; the resulting +slice is indexed from <code>0</code> through <code>high-low-1</code>. +In short, slices look a lot like arrays but with +no explicit size (<code>[]</code> vs. <code>[10]</code>) and they reference a segment of +an underlying, usually anonymous, regular array. Multiple slices +can share data if they represent pieces of the same array; +multiple arrays can never share data. +<p> +Slices are much more common in Go programs than +regular arrays; they're more flexible, have reference semantics, +and are efficient. What they lack is the precise control of storage +layout of a regular array; if you want to have a hundred elements +of an array stored within your structure, you should use a regular +array. To create one, use a compound value <i>constructor</i>—an +expression formed +from a type followed by a brace-bounded expression like this: +<p> +<pre> +[3]int{1,2,3} +</pre> +<p> +In this case the constructor builds an array of 3 <code>ints</code>. +<p> +When passing an array to a function, you almost always want +to declare the formal parameter to be a slice. When you call +the function, slice the array to create +(efficiently) a slice reference and pass that. +By default, the lower and upper bounds of a slice match the +ends of the existing object, so the concise notation <code>[:]</code> +will slice the whole array. +<p> +Using slices one can write this function (from <code>sum.go</code>): +<p> +{{code "progs/sum.go" `/sum/` `/^}/`}} +<p> +Note how the return type (<code>int</code>) is defined for <code>sum</code> by stating it +after the parameter list. +<p> +To call the function, we slice the array. This intricate call (we'll show +a simpler way in a moment) constructs +an array and slices it: +<p> +<pre> +s := sum([3]int{1,2,3}[:]) +</pre> +<p> +If you are creating a regular array but want the compiler to count the +elements for you, use <code>...</code> as the array size: +<p> +<pre> +s := sum([...]int{1,2,3}[:]) +</pre> +<p> +That's fussier than necessary, though. +In practice, unless you're meticulous about storage layout within a +data structure, a slice itself—using empty brackets with no size—is all you need: +<p> +<pre> +s := sum([]int{1,2,3}) +</pre> +<p> +There are also maps, which you can initialize like this: +<p> +<pre> +m := map[string]int{"one":1 , "two":2} +</pre> +<p> +The built-in function <code>len</code>, which returns number of elements, +makes its first appearance in <code>sum</code>. It works on strings, arrays, +slices, maps, and channels. +<p> +By the way, another thing that works on strings, arrays, slices, maps +and channels is the <code>range</code> clause on <code>for</code> loops. Instead of writing +<p> +<pre> +for i := 0; i < len(a); i++ { ... } +</pre> +<p> +to loop over the elements of a slice (or map or ...) , we could write +<p> +<pre> +for i, v := range a { ... } +</pre> +<p> +This assigns <code>i</code> to the index and <code>v</code> to the value of the successive +elements of the target of the range. See +<a href='/doc/effective_go.html'>Effective Go</a> +for more examples of its use. +<p> +<p> +<h2>An Interlude about Allocation</h2> +<p> +Most types in Go are values. If you have an <code>int</code> or a <code>struct</code> +or an array, assignment +copies the contents of the object. +To allocate a new variable, use the built-in function <code>new</code>, which +returns a pointer to the allocated storage. +<p> +<pre> +type T struct { a, b int } +var t *T = new(T) +</pre> +<p> +or the more idiomatic +<p> +<pre> +t := new(T) +</pre> +<p> +Some types—maps, slices, and channels (see below)—have reference semantics. +If you're holding a slice or a map and you modify its contents, other variables +referencing the same underlying data will see the modification. For these three +types you want to use the built-in function <code>make</code>: +<p> +<pre> +m := make(map[string]int) +</pre> +<p> +This statement initializes a new map ready to store entries. +If you just declare the map, as in +<p> +<pre> +var m map[string]int +</pre> +<p> +it creates a <code>nil</code> reference that cannot hold anything. To use the map, +you must first initialize the reference using <code>make</code> or by assignment from an +existing map. +<p> +Note that <code>new(T)</code> returns type <code>*T</code> while <code>make(T)</code> returns type +<code>T</code>. If you (mistakenly) allocate a reference object with <code>new</code> rather than <code>make</code>, +you receive a pointer to a nil reference, equivalent to +declaring an uninitialized variable and taking its address. +<p> +<h2>An Interlude about Constants</h2> +<p> +Although integers come in lots of sizes in Go, integer constants do not. +There are no constants like <code>0LL</code> or <code>0x0UL</code>. Instead, integer +constants are evaluated as large-precision values that +can overflow only when they are assigned to an integer variable with +too little precision to represent the value. +<p> +<pre> +const hardEight = (1 << 100) >> 97 // legal +</pre> +<p> +There are nuances that deserve redirection to the legalese of the +language specification but here are some illustrative examples: +<p> +<pre> +var a uint64 = 0 // a has type uint64, value 0 +a := uint64(0) // equivalent; uses a "conversion" +i := 0x1234 // i gets default type: int +var j int = 1e6 // legal - 1000000 is representable in an int +x := 1.5 // a float64, the default type for floating constants +i3div2 := 3/2 // integer division - result is 1 +f3div2 := 3./2. // floating-point division - result is 1.5 +</pre> +<p> +Conversions only work for simple cases such as converting <code>ints</code> of one +sign or size to another and between integers and floating-point numbers, +plus a couple of other instances outside the scope of a tutorial. +There are no automatic numeric conversions of any kind in Go, +other than that of making constants have concrete size and type when +assigned to a variable. +<p> +<h2>An I/O Package</h2> +<p> +Next we'll look at a simple package for doing file I/O with an +open/close/read/write interface. Here's the start of <code>file.go</code>: +<p> +{{code "progs/file.go" `/package/` `/^}/`}} +<p> +The first few lines declare the name of the +package—<code>file</code>—and then import two packages. The <code>os</code> +package hides the differences +between various operating systems to give a consistent view of files and +so on; here we're going to use its error handling utilities +and reproduce the rudiments of its file I/O. +<p> +The other item is the low-level, external <code>syscall</code> package, which provides +a primitive interface to the underlying operating system's calls. +<p> +Next is a type definition: the <code>type</code> keyword introduces a type declaration, +in this case a data structure called <code>File</code>. +To make things a little more interesting, our <code>File</code> includes the name of the file +that the file descriptor refers to. +<p> +Because <code>File</code> starts with a capital letter, the type is available outside the package, +that is, by users of the package. In Go the rule about visibility of information is +simple: if a name (of a top-level type, function, method, constant or variable, or of +a structure field or method) is capitalized, users of the package may see it. Otherwise, the +name and hence the thing being named is visible only inside the package in which +it is declared. This is more than a convention; the rule is enforced by the compiler. +In Go, the term for publicly visible names is ''exported''. +<p> +In the case of <code>File</code>, all its fields are lower case and so invisible to users, but we +will soon give it some exported, upper-case methods. +<p> +First, though, here is a factory to create a <code>File</code>: +<p> +{{code "progs/file.go" `/newFile/` `/^}/`}} +<p> +This returns a pointer to a new <code>File</code> structure with the file descriptor and name +filled in. This code uses Go's notion of a ''composite literal'', analogous to +the ones used to build maps and arrays, to construct a new heap-allocated +object. We could write +<p> +<pre> +n := new(File) +n.fd = fd +n.name = name +return n +</pre> +<p> +but for simple structures like <code>File</code> it's easier to return the address of a +composite literal, as is done here in the <code>return</code> statement from <code>newFile</code>. +<p> +We can use the factory to construct some familiar, exported variables of type <code>*File</code>: +<p> +{{code "progs/file.go" `/var/` `/^.$/`}} +<p> +The <code>newFile</code> function was not exported because it's internal. The proper, +exported factory to use is <code>OpenFile</code> (we'll explain that name in a moment): +<p> +{{code "progs/file.go" `/func.OpenFile/` `/^}/`}} +<p> +There are a number of new things in these few lines. First, <code>OpenFile</code> returns +multiple values, a <code>File</code> and an error (more about errors in a moment). +We declare the +multi-value return as a parenthesized list of declarations; syntactically +they look just like a second parameter list. The function +<code>syscall.Open</code> +also has a multi-value return, which we can grab with the multi-variable +declaration on the first line; it declares <code>r</code> and <code>e</code> to hold the two values, +both of type <code>int</code> (although you'd have to look at the <code>syscall</code> package +to see that). Finally, <code>OpenFile</code> returns two values: a pointer to the new <code>File</code> +and the error. If <code>syscall.Open</code> fails, the file descriptor <code>r</code> will +be negative and <code>newFile</code> will return <code>nil</code>. +<p> +About those errors: The <code>os</code> library includes a general notion of an error. +It's a good idea to use its facility in your own interfaces, as we do here, for +consistent error handling throughout Go code. In <code>Open</code> we use a +conversion to translate Unix's integer <code>errno</code> value into the integer type +<code>os.Errno</code>, which implements <code>os.Error</code>. +<p> +Why <code>OpenFile</code> and not <code>Open</code>? To mimic Go's <code>os</code> package, which +our exercise is emulating. The <code>os</code> package takes the opportunity +to make the two commonest cases - open for read and create for +write - the simplest, just <code>Open</code> and <code>Create</code>. <code>OpenFile</code> is the +general case, analogous to the Unix system call <code>Open</code>. Here is +the implementation of our <code>Open</code> and <code>Create</code>; they're trivial +wrappers that eliminate common errors by capturing +the tricky standard arguments to open and, especially, to create a file: +<p> +{{code "progs/file.go" `/^const/` `/^}/`}} +<p> +{{code "progs/file.go" `/func.Create/` `/^}/`}} +<p> +Back to our main story. +Now that we can build <code>Files</code>, we can write methods for them. To declare +a method of a type, we define a function to have an explicit receiver +of that type, placed +in parentheses before the function name. Here are some methods for <code>*File</code>, +each of which declares a receiver variable <code>file</code>. +<p> +{{code "progs/file.go" `/Close/` "$"}} +<p> +There is no implicit <code>this</code> and the receiver variable must be used to access +members of the structure. Methods are not declared within +the <code>struct</code> declaration itself. The <code>struct</code> declaration defines only data members. +In fact, methods can be created for almost any type you name, such as an integer or +array, not just for <code>structs</code>. We'll see an example with arrays later. +<p> +The <code>String</code> method is so called because of a printing convention we'll +describe later. +<p> +The methods use the public variable <code>os.EINVAL</code> to return the (<code>os.Error</code> +version of the) Unix error code <code>EINVAL</code>. The <code>os</code> library defines a standard +set of such error values. +<p> +We can now use our new package: +<p> +{{code "progs/helloworld3.go" `/package/` "$"}} +<p> +The ''<code>./</code>'' in the import of ''<code>./file</code>'' tells the compiler +to use our own package rather than +something from the directory of installed packages. +(Also, ''<code>file.go</code>'' must be compiled before we can import the +package.) +<p> +Now we can compile and run the program. On Unix, this would be the result: +<p> +<pre> +$ 6g file.go # compile file package +$ 6g helloworld3.go # compile main package +$ 6l -o helloworld3 helloworld3.6 # link - no need to mention "file" +$ helloworld3 +hello, world +can't open file; err=No such file or directory +$ +</pre> +<p> +<h2>Rotting cats</h2> +<p> +Building on the <code>file</code> package, here's a simple version of the Unix utility <code>cat(1)</code>, +<code>progs/cat.go</code>: +<p> +{{code "progs/cat.go" `/package/` "$"}} +<p> +By now this should be easy to follow, but the <code>switch</code> statement introduces some +new features. Like a <code>for</code> loop, an <code>if</code> or <code>switch</code> can include an +initialization statement. The <code>switch</code> statement in <code>cat</code> uses one to create variables +<code>nr</code> and <code>er</code> to hold the return values from the call to <code>f.Read</code>. (The <code>if</code> a few lines later +has the same idea.) The <code>switch</code> statement is general: it evaluates the cases +from top to bottom looking for the first case that matches the value; the +case expressions don't need to be constants or even integers, as long as +they all have the same type. +<p> +Since the <code>switch</code> value is just <code>true</code>, we could leave it off—as is also +the situation +in a <code>for</code> statement, a missing value means <code>true</code>. In fact, such a <code>switch</code> +is a form of <code>if-else</code> chain. While we're here, it should be mentioned that in +<code>switch</code> statements each <code>case</code> has an implicit <code>break</code>. +<p> +The argument to <code>file.Stdout.Write</code> is created by slicing the array <code>buf</code>. +Slices provide the standard Go way to handle I/O buffers. +<p> +Now let's make a variant of <code>cat</code> that optionally does <code>rot13</code> on its input. +It's easy to do by just processing the bytes, but instead we will exploit +Go's notion of an <i>interface</i>. +<p> +The <code>cat</code> subroutine uses only two methods of <code>f</code>: <code>Read</code> and <code>String</code>, +so let's start by defining an interface that has exactly those two methods. +Here is code from <code>progs/cat_rot13.go</code>: +<p> +{{code "progs/cat_rot13.go" `/type.reader/` `/^}/`}} +<p> +Any type that has the two methods of <code>reader</code>—regardless of whatever +other methods the type may also have—is said to <i>implement</i> the +interface. Since <code>file.File</code> implements these methods, it implements the +<code>reader</code> interface. We could tweak the <code>cat</code> subroutine to accept a <code>reader</code> +instead of a <code>*file.File</code> and it would work just fine, but let's embellish a little +first by writing a second type that implements <code>reader</code>, one that wraps an +existing <code>reader</code> and does <code>rot13</code> on the data. To do this, we just define +the type and implement the methods and with no other bookkeeping, +we have a second implementation of the <code>reader</code> interface. +<p> +{{code "progs/cat_rot13.go" `/type.rotate13/` `/end.of.rotate13/`}} +<p> +(The <code>rot13</code> function called in <code>Read</code> is trivial and not worth reproducing here.) +<p> +To use the new feature, we define a flag: +<p> +{{code "progs/cat_rot13.go" `/rot13Flag/`}} +<p> +and use it from within a mostly unchanged <code>cat</code> function: +<p> +{{code "progs/cat_rot13.go" `/func.cat/` `/^}/`}} +<p> +(We could also do the wrapping in <code>main</code> and leave <code>cat</code> mostly alone, except +for changing the type of the argument; consider that an exercise.) +The <code>if</code> at the top of <code>cat</code> sets it all up: If the <code>rot13</code> flag is true, wrap the <code>reader</code> +we received into a <code>rotate13</code> and proceed. Note that the interface variables +are values, not pointers: the argument is of type <code>reader</code>, not <code>*reader</code>, +even though under the covers it holds a pointer to a <code>struct</code>. +<p> +Here it is in action: +<p> +<pre> +$ echo abcdefghijklmnopqrstuvwxyz | ./cat +abcdefghijklmnopqrstuvwxyz +$ echo abcdefghijklmnopqrstuvwxyz | ./cat --rot13 +nopqrstuvwxyzabcdefghijklm +$ +</pre> +<p> +Fans of dependency injection may take cheer from how easily interfaces +allow us to substitute the implementation of a file descriptor. +<p> +Interfaces are a distinctive feature of Go. An interface is implemented by a +type if the type implements all the methods declared in the interface. +This means +that a type may implement an arbitrary number of different interfaces. +There is no type hierarchy; things can be much more <i>ad hoc</i>, +as we saw with <code>rot13</code>. The type <code>file.File</code> implements <code>reader</code>; it could also +implement a <code>writer</code>, or any other interface built from its methods that +fits the current situation. Consider the <i>empty interface</i> +<p> +<pre> +type Empty interface {} +</pre> +<p> +<i>Every</i> type implements the empty interface, which makes it +useful for things like containers. +<p> +<h2>Sorting</h2> +<p> +Interfaces provide a simple form of polymorphism. They completely +separate the definition of what an object does from how it does it, allowing +distinct implementations to be represented at different times by the +same interface variable. +<p> +As an example, consider this simple sort algorithm taken from <code>progs/sort.go</code>: +<p> +{{code "progs/sort.go" `/func.Sort/` `/^}/`}} +<p> +The code needs only three methods, which we wrap into sort's <code>Interface</code>: +<p> +{{code "progs/sort.go" `/interface/` `/^}/`}} +<p> +We can apply <code>Sort</code> to any type that implements <code>Len</code>, <code>Less</code>, and <code>Swap</code>. +The <code>sort</code> package includes the necessary methods to allow sorting of +arrays of integers, strings, etc.; here's the code for arrays of <code>int</code> +<p> +{{code "progs/sort.go" `/type.*IntSlice/` `/Swap/`}} +<p> +Here we see methods defined for non-<code>struct</code> types. You can define methods +for any type you define and name in your package. +<p> +And now a routine to test it out, from <code>progs/sortmain.go</code>. This +uses a function in the <code>sort</code> package, omitted here for brevity, +to test that the result is sorted. +<p> +{{code "progs/sortmain.go" `/func.ints/` `/^}/`}} +<p> +If we have a new type we want to be able to sort, all we need to do is +to implement the three methods for that type, like this: +<p> +{{code "progs/sortmain.go" `/type.day/` `/Swap/`}} +<p> +<p> +<h2>Printing</h2> +<p> +The examples of formatted printing so far have been modest. In this section +we'll talk about how formatted I/O can be done well in Go. +<p> +We've seen simple uses of the package <code>fmt</code>, which +implements <code>Printf</code>, <code>Fprintf</code>, and so on. +Within the <code>fmt</code> package, <code>Printf</code> is declared with this signature: +<p> +<pre> +Printf(format string, v ...interface{}) (n int, errno os.Error) +</pre> +<p> +The token <code>...</code> introduces a variable-length argument list that in C would +be handled using the <code>stdarg.h</code> macros. +In Go, variadic functions are passed a slice of the arguments of the +specified type. In <code>Printf</code>'s case, the declaration says <code>...interface{}</code> +so the actual type is a slice of empty interface values, <code>[]interface{}</code>. +<code>Printf</code> can examine the arguments by iterating over the slice +and, for each element, using a type switch or the reflection library +to interpret the value. +It's off topic here but such run-time type analysis +helps explain some of the nice properties of Go's <code>Printf</code>, +due to the ability of <code>Printf</code> to discover the type of its arguments +dynamically. +<p> +For example, in C each format must correspond to the type of its +argument. It's easier in many cases in Go. Instead of <code>%llud</code> you +can just say <code>%d</code>; <code>Printf</code> knows the size and signedness of the +integer and can do the right thing for you. The snippet +<p> +{{code "progs/print.go" 10 11}} +<p> +prints +<p> +<pre> +18446744073709551615 -1 +</pre> +<p> +In fact, if you're lazy the format <code>%v</code> will print, in a simple +appropriate style, any value, even an array or structure. The output of +<p> +{{code "progs/print.go" 14 20}} +<p> +is +<p> +<pre> +18446744073709551615 {77 Sunset Strip} [1 2 3 4] +</pre> +<p> +You can drop the formatting altogether if you use <code>Print</code> or <code>Println</code> +instead of <code>Printf</code>. Those routines do fully automatic formatting. +The <code>Print</code> function just prints its elements out using the equivalent +of <code>%v</code> while <code>Println</code> inserts spaces between arguments +and adds a newline. The output of each of these two lines is identical +to that of the <code>Printf</code> call above. +<p> +{{code "progs/print.go" 21 22}} +<p> +If you have your own type you'd like <code>Printf</code> or <code>Print</code> to format, +just give it a <code>String</code> method that returns a string. The print +routines will examine the value to inquire whether it implements +the method and if so, use it rather than some other formatting. +Here's a simple example. +<p> +{{code "progs/print_string.go" 9 "$"}} +<p> +Since <code>*testType</code> has a <code>String</code> method, the +default formatter for that type will use it and produce the output +<p> +<pre> +77 Sunset Strip +</pre> +<p> +Observe that the <code>String</code> method calls <code>Sprint</code> (the obvious Go +variant that returns a string) to do its formatting; special formatters +can use the <code>fmt</code> library recursively. +<p> +Another feature of <code>Printf</code> is that the format <code>%T</code> will print a string +representation of the type of a value, which can be handy when debugging +polymorphic code. +<p> +It's possible to write full custom print formats with flags and precisions +and such, but that's getting a little off the main thread so we'll leave it +as an exploration exercise. +<p> +You might ask, though, how <code>Printf</code> can tell whether a type implements +the <code>String</code> method. Actually what it does is ask if the value can +be converted to an interface variable that implements the method. +Schematically, given a value <code>v</code>, it does this: +<p> +<p> +<pre> +type Stringer interface { + String() string +} +</pre> +<p> +<pre> +s, ok := v.(Stringer) // Test whether v implements "String()" +if ok { + result = s.String() +} else { + result = defaultOutput(v) +} +</pre> +<p> +The code uses a ``type assertion'' (<code>v.(Stringer)</code>) to test if the value stored in +<code>v</code> satisfies the <code>Stringer</code> interface; if it does, <code>s</code> +will become an interface variable implementing the method and <code>ok</code> will +be <code>true</code>. We then use the interface variable to call the method. +(The ''comma, ok'' pattern is a Go idiom used to test the success of +operations such as type conversion, map update, communications, and so on, +although this is the only appearance in this tutorial.) +If the value does not satisfy the interface, <code>ok</code> will be false. +<p> +In this snippet the name <code>Stringer</code> follows the convention that we add ''[e]r'' +to interfaces describing simple method sets like this. +<p> +One last wrinkle. To complete the suite, besides <code>Printf</code> etc. and <code>Sprintf</code> +etc., there are also <code>Fprintf</code> etc. Unlike in C, <code>Fprintf</code>'s first argument is +not a file. Instead, it is a variable of type <code>io.Writer</code>, which is an +interface type defined in the <code>io</code> library: +<p> +<pre> +type Writer interface { + Write(p []byte) (n int, err os.Error) +} +</pre> +<p> +(This interface is another conventional name, this time for <code>Write</code>; there are also +<code>io.Reader</code>, <code>io.ReadWriter</code>, and so on.) +Thus you can call <code>Fprintf</code> on any type that implements a standard <code>Write</code> +method, not just files but also network channels, buffers, whatever +you want. +<p> +<h2>Prime numbers</h2> +<p> +Now we come to processes and communication—concurrent programming. +It's a big subject so to be brief we assume some familiarity with the topic. +<p> +A classic program in the style is a prime sieve. +(The sieve of Eratosthenes is computationally more efficient than +the algorithm presented here, but we are more interested in concurrency than +algorithmics at the moment.) +It works by taking a stream of all the natural numbers and introducing +a sequence of filters, one for each prime, to winnow the multiples of +that prime. At each step we have a sequence of filters of the primes +so far, and the next number to pop out is the next prime, which triggers +the creation of the next filter in the chain. +<p> +Here's a flow diagram; each box represents a filter element whose +creation is triggered by the first number that flowed from the +elements before it. +<p> +<br> +<p> + <img src='sieve.gif'> +<p> +<br> +<p> +To create a stream of integers, we use a Go <i>channel</i>, which, +borrowing from CSP's descendants, represents a communications +channel that can connect two concurrent computations. +In Go, channel variables are references to a run-time object that +coordinates the communication; as with maps and slices, use +<code>make</code> to create a new channel. +<p> +Here is the first function in <code>progs/sieve.go</code>: +<p> +{{code "progs/sieve.go" `/Send/` `/^}/`}} +<p> +The <code>generate</code> function sends the sequence 2, 3, 4, 5, ... to its +argument channel, <code>ch</code>, using the binary communications operator <code><-</code>. +Channel operations block, so if there's no recipient for the value on <code>ch</code>, +the send operation will wait until one becomes available. +<p> +The <code>filter</code> function has three arguments: an input channel, an output +channel, and a prime number. It copies values from the input to the +output, discarding anything divisible by the prime. The unary communications +operator <code><-</code> (receive) retrieves the next value on the channel. +<p> +{{code "progs/sieve.go" `/Copy.the/` `/^}/`}} +<p> +The generator and filters execute concurrently. Go has +its own model of process/threads/light-weight processes/coroutines, +so to avoid notational confusion we call concurrently executing +computations in Go <i>goroutines</i>. To start a goroutine, +invoke the function, prefixing the call with the keyword <code>go</code>; +this starts the function running in parallel with the current +computation but in the same address space: +<p> +<pre> +go sum(hugeArray) // calculate sum in the background +</pre> +<p> +If you want to know when the calculation is done, pass a channel +on which it can report back: +<p> +<pre> +ch := make(chan int) +go sum(hugeArray, ch) +// ... do something else for a while +result := <-ch // wait for, and retrieve, result +</pre> +<p> +Back to our prime sieve. Here's how the sieve pipeline is stitched +together: +<p> +{{code "progs/sieve.go" `/func.main/` `/^}/`}} +<p> +The first line of <code>main</code> creates the initial channel to pass to <code>generate</code>, which it +then starts up. As each prime pops out of the channel, a new <code>filter</code> +is added to the pipeline and <i>its</i> output becomes the new value +of <code>ch</code>. +<p> +The sieve program can be tweaked to use a pattern common +in this style of programming. Here is a variant version +of <code>generate</code>, from <code>progs/sieve1.go</code>: +<p> +{{code "progs/sieve1.go" `/func.generate/` `/^}/`}} +<p> +This version does all the setup internally. It creates the output +channel, launches a goroutine running a function literal, and +returns the channel to the caller. It is a factory for concurrent +execution, starting the goroutine and returning its connection. +<p> +The function literal notation used in the <code>go</code> statement allows us to construct an +anonymous function and invoke it on the spot. Notice that the local +variable <code>ch</code> is available to the function literal and lives on even +after <code>generate</code> returns. +<p> +The same change can be made to <code>filter</code>: +<p> +{{code "progs/sieve1.go" `/func.filter/` `/^}/`}} +<p> +The <code>sieve</code> function's main loop becomes simpler and clearer as a +result, and while we're at it let's turn it into a factory too: +<p> +{{code "progs/sieve1.go" `/func.sieve/` `/^}/`}} +<p> +Now <code>main</code>'s interface to the prime sieve is a channel of primes: +<p> +{{code "progs/sieve1.go" `/func.main/` `/^}/`}} +<p> +<h2>Multiplexing</h2> +<p> +With channels, it's possible to serve multiple independent client goroutines without +writing an explicit multiplexer. The trick is to send the server a channel in the message, +which it will then use to reply to the original sender. +A realistic client-server program is a lot of code, so here is a very simple substitute +to illustrate the idea. It starts by defining a <code>request</code> type, which embeds a channel +that will be used for the reply. +<p> +{{code "progs/server.go" `/type.request/` `/^}/`}} +<p> +The server will be trivial: it will do simple binary operations on integers. Here's the +code that invokes the operation and responds to the request: +<p> +{{code "progs/server.go" `/type.binOp/` `/^}/`}} +<p> +The type declaration makes <code>binOp</code> represent a function taking two integers and +returning a third. +<p> +The <code>server</code> routine loops forever, receiving requests and, to avoid blocking due to +a long-running operation, starting a goroutine to do the actual work. +<p> +{{code "progs/server.go" `/func.server/` `/^}/`}} +<p> +We construct a server in a familiar way, starting it and returning a channel +connected to it: +<p> +{{code "progs/server.go" `/func.startServer/` `/^}/`}} +<p> +Here's a simple test. It starts a server with an addition operator and sends out +<code>N</code> requests without waiting for the replies. Only after all the requests are sent +does it check the results. +<p> +{{code "progs/server.go" `/func.main/` `/^}/`}} +<p> +One annoyance with this program is that it doesn't shut down the server cleanly; when <code>main</code> returns +there are a number of lingering goroutines blocked on communication. To solve this, +we can provide a second, <code>quit</code> channel to the server: +<p> +{{code "progs/server1.go" `/func.startServer/` `/^}/`}} +<p> +It passes the quit channel to the <code>server</code> function, which uses it like this: +<p> +{{code "progs/server1.go" `/func.server/` `/^}/`}} +<p> +Inside <code>server</code>, the <code>select</code> statement chooses which of the multiple communications +listed by its cases can proceed. If all are blocked, it waits until one can proceed; if +multiple can proceed, it chooses one at random. In this instance, the <code>select</code> allows +the server to honor requests until it receives a quit message, at which point it +returns, terminating its execution. +<p> +<p> +All that's left is to strobe the <code>quit</code> channel +at the end of main: +<p> +{{code "progs/server1.go" `/adder,.quit/`}} +... +{{code "progs/server1.go" `/quit....true/`}} +<p> +There's a lot more to Go programming and concurrent programming in general but this +quick tour should give you some of the basics. diff --git a/doc/godocs.js b/doc/godocs.js new file mode 100644 index 000000000..946c4c39f --- /dev/null +++ b/doc/godocs.js @@ -0,0 +1,190 @@ +// Except as noted, this content is licensed under Creative Commons +// Attribution 3.0 + +/* A little code to ease navigation of these documents. + * + * On window load we: + * + Generate a table of contents (godocs_generateTOC) + * + Add links up to the top of the doc from each section (godocs_addTopLinks) + */ + +/* We want to do some stuff on page load (after the HTML is rendered). + So listen for that: + */ +function bindEvent(el, e, fn) { + if (el.addEventListener){ + el.addEventListener(e, fn, false); + } else if (el.attachEvent){ + el.attachEvent('on'+e, fn); + } +} +bindEvent(window, 'load', godocs_onload); + +function godocs_onload() { + godocs_bindSearchEvents(); + godocs_generateTOC(); + godocs_addTopLinks(); +} + +function godocs_bindSearchEvents() { + var search = document.getElementById('search'); + if (!search) { + // no search box (index disabled) + return; + } + function clearInactive() { + if (search.className == "inactive") { + search.value = ""; + search.className = ""; + } + } + function restoreInactive() { + if (search.value != "") { + return; + } + if (search.type != "search") { + search.value = search.getAttribute("placeholder"); + } + search.className = "inactive"; + } + restoreInactive(); + bindEvent(search, 'focus', clearInactive); + bindEvent(search, 'blur', restoreInactive); +} + +/* Generates a table of contents: looks for h2 and h3 elements and generates + * links. "Decorates" the element with id=="nav" with this table of contents. + */ +function godocs_generateTOC() { + var navbar = document.getElementById('nav'); + if (!navbar) { return; } + + var toc_items = []; + + var i; + for (i = 0; i < navbar.parentNode.childNodes.length; i++) { + var node = navbar.parentNode.childNodes[i]; + if ((node.tagName == 'h2') || (node.tagName == 'H2')) { + if (!node.id) { + node.id = 'tmp_' + i; + } + var text = godocs_nodeToText(node); + if (!text) { continue; } + + var textNode = document.createTextNode(text); + + var link = document.createElement('a'); + link.href = '#' + node.id; + link.appendChild(textNode); + + // Then create the item itself + var item = document.createElement('dt'); + + item.appendChild(link); + toc_items.push(item); + } + if ((node.tagName == 'h3') || (node.tagName == 'H3')) { + if (!node.id) { + node.id = 'tmp_' + i; + } + var text = godocs_nodeToText(node); + if (!text) { continue; } + + var textNode = document.createTextNode(text); + + var link = document.createElement('a'); + link.href = '#' + node.id; + link.appendChild(textNode); + + // Then create the item itself + var item = document.createElement('dd'); + + item.appendChild(link); + toc_items.push(item); + } + } + + if (toc_items.length <= 1) { return; } + + var dl1 = document.createElement('dl'); + var dl2 = document.createElement('dl'); + + var split_index = (toc_items.length / 2) + 1; + if (split_index < 8) { + split_index = toc_items.length; + } + + for (i = 0; i < split_index; i++) { + dl1.appendChild(toc_items[i]); + } + for (/* keep using i */; i < toc_items.length; i++) { + dl2.appendChild(toc_items[i]); + } + + var tocTable = document.createElement('table'); + navbar.appendChild(tocTable); + tocTable.className = 'unruled'; + var tocBody = document.createElement('tbody'); + tocTable.appendChild(tocBody); + + var tocRow = document.createElement('tr'); + tocBody.appendChild(tocRow); + + // 1st column + var tocCell = document.createElement('td'); + tocCell.className = 'first'; + tocRow.appendChild(tocCell); + tocCell.appendChild(dl1); + + // 2nd column + tocCell = document.createElement('td'); + tocRow.appendChild(tocCell); + tocCell.appendChild(dl2); +} + +/* Returns the "This sweet header" from <h2>This <i>sweet</i> header</h2>. + * Takes a node, returns a string. + */ +function godocs_nodeToText(node) { + var TEXT_NODE = 3; // Defined in Mozilla but not MSIE :( + + var text = ''; + for (var j = 0; j != node.childNodes.length; j++) { + var child = node.childNodes[j]; + if (child.nodeType == TEXT_NODE) { + if (child.nodeValue != '[Top]') { //ok, that's a hack, but it works. + text = text + child.nodeValue; + } + } else { + text = text + godocs_nodeToText(child); + } + } + return text; +} + +/* For each H2 heading, add a link up to the #top of the document. + * (As part of this: ensure existence of 'top' named anchor link + * (theoretically at doc's top).) + */ +function godocs_addTopLinks() { + /* Make sure there's a "top" to link to. */ + var top = document.getElementById('top'); + if (!top) { + document.body.id = 'top'; + } + + if (!document.getElementsByTagName) return; // no browser support + + var headers = document.getElementsByTagName('h2'); + + for (var i = 0; i < headers.length; i++) { + var span = document.createElement('span'); + span.className = 'navtop'; + var link = document.createElement('a'); + span.appendChild(link); + link.href = '#top'; + var textNode = document.createTextNode('[Top]'); + link.appendChild(textNode); + headers[i].appendChild(span); + } +} diff --git a/doc/gopher/appenginegopher.jpg b/doc/gopher/appenginegopher.jpg Binary files differnew file mode 100644 index 000000000..0a6430666 --- /dev/null +++ b/doc/gopher/appenginegopher.jpg diff --git a/doc/gopher/appenginegophercolor.jpg b/doc/gopher/appenginegophercolor.jpg Binary files differnew file mode 100644 index 000000000..68795a99b --- /dev/null +++ b/doc/gopher/appenginegophercolor.jpg diff --git a/doc/gopher/appenginelogo.gif b/doc/gopher/appenginelogo.gif Binary files differnew file mode 100644 index 000000000..46b3c1eeb --- /dev/null +++ b/doc/gopher/appenginelogo.gif diff --git a/doc/gopher/bumper.png b/doc/gopher/bumper.png Binary files differnew file mode 100644 index 000000000..6b41c1fd0 --- /dev/null +++ b/doc/gopher/bumper.png diff --git a/doc/gopher/bumper192x108.png b/doc/gopher/bumper192x108.png Binary files differnew file mode 100644 index 000000000..470a74df5 --- /dev/null +++ b/doc/gopher/bumper192x108.png diff --git a/doc/gopher/bumper320x180.png b/doc/gopher/bumper320x180.png Binary files differnew file mode 100644 index 000000000..5b31b5d31 --- /dev/null +++ b/doc/gopher/bumper320x180.png diff --git a/doc/gopher/bumper480x270.png b/doc/gopher/bumper480x270.png Binary files differnew file mode 100644 index 000000000..621f51b65 --- /dev/null +++ b/doc/gopher/bumper480x270.png diff --git a/doc/gopher/bumper640x360.png b/doc/gopher/bumper640x360.png Binary files differnew file mode 100644 index 000000000..9c898d0c7 --- /dev/null +++ b/doc/gopher/bumper640x360.png diff --git a/doc/gopher/gopherbw.png b/doc/gopher/gopherbw.png Binary files differnew file mode 100644 index 000000000..48a08cc61 --- /dev/null +++ b/doc/gopher/gopherbw.png diff --git a/doc/gopher/gophercolor.png b/doc/gopher/gophercolor.png Binary files differnew file mode 100644 index 000000000..b48ffba37 --- /dev/null +++ b/doc/gopher/gophercolor.png diff --git a/doc/gopher/gophercolor16x16.png b/doc/gopher/gophercolor16x16.png Binary files differnew file mode 100644 index 000000000..48854ff3b --- /dev/null +++ b/doc/gopher/gophercolor16x16.png diff --git a/doc/ie.css b/doc/ie.css new file mode 100644 index 000000000..bb89d54be --- /dev/null +++ b/doc/ie.css @@ -0,0 +1 @@ +#nav-main li { display: inline; } diff --git a/doc/install.html b/doc/install.html new file mode 100644 index 000000000..a1bc89982 --- /dev/null +++ b/doc/install.html @@ -0,0 +1,474 @@ +<!-- Getting Started --> + +<h2 id="introduction">Introduction</h2> + +<p>Go is an open source project, distributed under a +<a href="/LICENSE">BSD-style license</a>. +This document explains how to check out the sources, +build them on your own machine, and run them. +</p> + +<div class="detail"> + +<p> +There are two distinct ways to experiment with Go. +This document focuses on the <code>gc</code> Go +compiler and tools (<code>6g</code>, <code>8g</code> etc.). +For information on how to use <code>gccgo</code>, a more traditional +compiler using the GCC back end, see +<a href="gccgo_install.html">Setting up and using gccgo</a>. +</p> + +<p> +The Go compilers support three instruction sets. +There are important differences in the quality of the compilers for the different +architectures. +</p> + +<dl> +<dt> + <code>amd64</code> (a.k.a. <code>x86-64</code>); <code>6g,6l,6c,6a</code> +</dt> +<dd> + The most mature implementation. The compiler has an effective optimizer + (registerizer) and generates good code (although <code>gccgo</code> + can do noticeably better sometimes). +</dd> +<dt> + <code>386</code> (a.k.a. <code>x86</code> or <code>x86-32</code>); <code>8g,8l,8c,8a</code> +</dt> +<dd> + Comparable to the <code>amd64</code> port. +</dd> +<dt> + <code>arm</code> (a.k.a. <code>ARM</code>); <code>5g,5l,5c,5a</code> +</dt> +<dd> + Incomplete. + It only supports Linux binaries, the optimizer is incomplete, + and floating point uses the VFP unit. + However, all tests pass. + Work on the optimizer is continuing. + Tested against a Nexus One. +</dd> +</dl> + +<p> +Except for things like low-level operating system interface code, the run-time +support is the same in all ports and includes a mark-and-sweep garbage collector +(a fancier one is in the works), efficient array and string slicing, +support for segmented stacks, and a strong goroutine implementation. +</p> + +<p> +The compilers can target the FreeBSD, Linux, +and OS X (a.k.a. Darwin) operating systems. +(A port to Microsoft Windows is in progress but incomplete. See the +<a href="http://code.google.com/p/go/wiki/WindowsPort">Windows Port</a> +page for details.) +The full set of supported combinations is listed in the discussion of +<a href="#environment">environment variables</a> below. +</p> + +</div> + +<h2 id="ctools">Install C tools, if needed</h2> + +<p>The Go tool chain is written in C. +To build it, you need these programs installed: +<ul> +<li>GCC, +<li>the standard C libraries, +<li>the parser generator Bison, +<li>GNU <tt>make</tt> (version 3.81 or later), +and +<li><tt>awk</tt>. +</ul> +</p> + +<p>On OS X, they can be +installed as part of +<a href="http://developer.apple.com/TOOLS/Xcode/">Xcode</a>. +</p> + +<p>On Ubuntu/Debian, use <code>sudo apt-get install bison gawk gcc libc6-dev +make</code>. If you want to build 32-bit binaries on a 64-bit system you'll +also need the <code>libc6-dev-i386</code> package. +</p> + +<h2 id="mercurial">Install Mercurial, if needed</h2> + +<p> +To perform the next step you must have Mercurial installed. (Check that you have an <code>hg</code> command.) This suffices to install Mercurial on most systems: +</p> +<pre> +sudo easy_install mercurial +</pre> +(On Ubuntu/Debian, you might try <code>apt-get install python-setuptools +python-dev build-essential</code> first. The Mercurial in your distribution's +package repository will most likely be old and broken.) +</p> +<p> +If that fails, try installing manually from the <a href="http://mercurial.selenic.com/wiki/Download">Mercurial Download</a> page.</p> +</p> + +<p> +Mercurial versions 1.7.x and up require the configuration of +<a href="http://mercurial.selenic.com/wiki/CACertificates">Certification Authorities</a> +(CAs). Error messages of the form: +</p> +<pre> +warning: go.googlecode.com certificate with fingerprint b1:af: ... bc not verified (check hostfingerprints or web.cacerts config setting) +</pre> +<p> +when using Mercurial indicate that the CAs are missing. +Check your Mercurial version (<code>hg --version</code>) and +<a href="http://mercurial.selenic.com/wiki/CACertificates#Configuration_of_HTTPS_certificate_authorities">configure the CAs</a> +if necessary. +</p> + +<h2 id="fetch">Fetch the repository</h2> + +<p> +<p>Go will install to a directory named <code>go</code>. +Change to the directory that will be its parent +and make sure the <code>go</code> directory does not exist. +Then check out the repository:</p> + +<pre> +$ hg clone -u release https://go.googlecode.com/hg/ go +</pre> + +<h2 id="install">Install Go</h2> + +<p> +To build the Go distribution, run +</p> + +<pre> +$ cd go/src +$ ./all.bash +</pre> + +<p> +If all goes well, it will finish by printing output like: +</p> + +<pre> +ALL TESTS PASSED + +--- +Installed Go for linux/amd64 in /home/you/go. +Installed commands in /home/you/go/bin. +*** You need to add /home/you/go/bin to your $PATH. *** +The compiler is 6g. +</pre> + +<p> +where the details on the last few lines reflect the operating system, +architecture, and root directory used during the install. +</p> + +<div class="detail"> + +<p>For more information about ways to control the build, +see the discussion of <a href="#environment">environment variables</a> below.</p> +</div> + +<h2 id="writing">Writing programs</h2> + +<p> +Given a file <code>file.go</code>, compile it using +</p> + +<pre> +$ 6g file.go +</pre> + +<p> +<code>6g</code> is the Go compiler for <code>amd64</code>; it will write the output +in <code>file.6</code>. The ‘<code>6</code>’ identifies +files for the <code>amd64</code> architecture. +The identifier letters for <code>386</code> and <code>arm</code> +are ‘<code>8</code>’ and ‘<code>5</code>’. +That is, if you were compiling for <code>386</code>, you would use +<code>8g</code> and the output would be named <code>file.8</code>. +</p> + +<p> +To link the file, use +</p> + +<pre> +$ 6l file.6 +</pre> + +<p> +and to run it +</p> + +<pre> +$ ./6.out +</pre> + +<p>A complete example: +</p> + +<pre> +$ cat >hello.go <<EOF +package main + +import "fmt" + +func main() { + fmt.Printf("hello, world\n") +} +EOF +$ 6g hello.go +$ 6l hello.6 +$ ./6.out +hello, world +$ +</pre> + +<p> +There is no need to list <code>hello.6</code>'s package dependencies +(in this case, package <code>fmt</code>) on the <code>6l</code> +command line. +The linker learns about them by reading <code>hello.6</code>. +</p> + +<div class="detail"> +<p> +To build more complicated programs, you will probably +want to use a +<code>Makefile</code>. +There are examples in places like +<code>go/src/cmd/godoc/Makefile</code> +and <code>go/src/pkg/*/Makefile</code>. +The +<a href="contribute.html">document</a> +about contributing to the Go project +gives more detail about +the process of building and testing Go programs. +</p> +</div> + +<h2 id="next">What's next</h2> + +<p> +Start by reading the <a href="go_tutorial.html">Go Tutorial</a>. +</p> + +<p> +Build a web application by following the <a href="codelab/wiki/">Wiki +Codelab</a>. +</p> + +<p> +Read <a href="effective_go.html">Effective Go</a> to learn about writing +idiomatic Go code. +</p> + +<p> +For the full story, consult Go's extensive +<a href="docs.html">documentation</a>. +</p> + +<h2 id="releases">Keeping up with releases</h2> + +<p> +The Go project maintains two stable tags in its Mercurial repository: +<code>release</code> and <code>weekly</code>. +The <code>weekly</code> tag is updated about once a week, and should be used by +those who want to track the project's development. +The <code>release</code> tag is given, less often, to those weekly releases +that have proven themselves to be robust. +</p> + +<p> +Most Go users will want to keep their Go installation at the latest +<code>release</code> tag. +New releases are announced on the +<a href="http://groups.google.com/group/golang-announce">golang-announce</a> +mailing list. +</p> + +<p> +To update an existing tree to the latest release, you can run: +</p> + +<pre> +$ cd go/src +$ hg pull +$ hg update release +$ ./all.bash +</pre> + +<p> +To use the <code>weekly</code> tag run <code>hg update weekly</code> instead. +</p> + +<h2 id="community">Community resources</h2> + +<p> +For real-time help, there may be users or developers on +<code>#go-nuts</code> on the <a href="http://freenode.net/">Freenode</a> IRC server. +</p> + +<p> +The official mailing list for discussion of the Go language is +<a href="http://groups.google.com/group/golang-nuts">Go Nuts</a>. +</p> + +<p> +Bugs can be reported using the <a href="http://code.google.com/p/go/issues/list">Go issue tracker</a>. +</p> + +<p> +For those who wish to keep up with development, +there is another mailing list, <a href="http://groups.google.com/group/golang-checkins">golang-checkins</a>, +that receives a message summarizing each checkin to the Go repository. +</p> + +<h2 id="environment">Environment variables</h2> + +<p> +The Go compilation environment can be customized by environment variables. +None are required by the build, but you may wish to set them +to override the defaults. +</p> + +<dl> +<dt> + <code>$GOROOT</code> +</dt> +<dd> + The root of the Go tree, often <code>$HOME/go</code>. + This defaults to the parent of the directory where <code>all.bash</code> is run. + If you choose not to set <code>$GOROOT</code>, you must + run <code>gomake</code> instead of <code>make</code> or <code>gmake</code> + when developing Go programs using the conventional makefiles. +</dd> + +<dt> + <code>$GOROOT_FINAL</code> +</dt> +<dd> + The value assumed by installed binaries and scripts when + <code>$GOROOT</code> is not set. + It defaults to the value used for <code>$GOROOT</code>. + If you want to build the Go tree in one location + but move it elsewhere after the build, set + <code>$GOROOT_FINAL</code> to the eventual location. +</dd> + +<dt> +<code>$GOOS</code> and <code>$GOARCH</code> +</dt> +<dd> + The name of the target operating system and compilation architecture. + These default to the values of <code>$GOHOSTOS</code> and + <code>$GOHOSTARCH</code> respectively (described below). + + <p> + Choices for <code>$GOOS</code> are <code>linux</code>, + <code>freebsd</code>, + <code>darwin</code> (Mac OS X 10.5 or 10.6), + and <code>windows</code> (Windows, an incomplete port). + Choices for <code>$GOARCH</code> are <code>amd64</code> (64-bit x86, the most mature port), + <code>386</code> (32-bit x86), and + <code>arm</code> (32-bit ARM, an incomplete port). + The valid combinations of <code>$GOOS</code> and <code>$GOARCH</code> are: + <table cellpadding="0"> + <tr> + <th width="50"><th align="left" width="100"><code>$GOOS</code></th> <th align="left" width="100"><code>$GOARCH</code></th> <th align="left"></th> + </tr> + <tr> + <td></td><td><code>darwin</code></td> <td><code>386</code></td> + </tr> + <tr> + <td></td><td><code>darwin</code></td> <td><code>amd64</code></td> + </tr> + <tr> + <td></td><td><code>freebsd</code></td> <td><code>386</code></td> + </tr> + <tr> + <td></td><td><code>freebsd</code></td> <td><code>amd64</code></td> + </tr> + <tr> + <td></td><td><code>linux</code></td> <td><code>386</code></td> + </tr> + <tr> + <td></td><td><code>linux</code></td> <td><code>amd64</code></td> + </tr> + <tr> + <td></td><td><code>linux</code></td> <td><code>arm</code></td> <td><i>incomplete</i></td> + </tr> + <tr> + <td></td><td><code>windows</code></td> <td><code>386</code></td> <td><i>incomplete</i></td> + </tr> + </table> +</dd> + +<dt> +<code>$GOHOSTOS</code> and <code>$GOHOSTARCH</code> +</dt> +<dd> + The name of the host operating system and compilation architecture. + These default to the local system's operating system and + architecture. + + <p> + Valid choices are the same as for <code>$GOOS</code> and + <code>$GOARCH</code>, listed above. + The specified values must be compatible with the local system. + For example, you should not set <code>$GOHOSTARCH</code> to + <code>arm</code> on an x86 system. +</dd> + +<dt> +<code>$GOBIN</code> +</dt> +<dd> + The location where binaries will be installed. + The default is <code>$GOROOT/bin</code>. + After installing, you will want to arrange to add this + directory to your <code>$PATH</code>, so you can use the tools. +</dd> + +<dt> +<code>$GOARM</code> (arm, default=6) +</dt> +<dd> + The ARM architecture version the run-time libraries should target. + ARMv6 cores have more efficient synchronization primitives. Setting + <code>$GOARM</code> to 5 will compile the run-time libraries using + just SWP instructions that work on older architectures as well. + Running v6 code on an older core will cause an illegal instruction trap. +</dd> +</dl> + +<p> +Note that <code>$GOARCH</code> and <code>$GOOS</code> identify the +<em>target</em> environment, not the environment you are running on. +In effect, you are always cross-compiling. +By architecture, we mean the kind of binaries +that the target environment can run: +an x86-64 system running a 32-bit-only operating system +must set <code>GOARCH</code> to <code>386</code>, +not <code>amd64</code>. +</p> + +<p> +If you choose to override the defaults, +set these variables in your shell profile (<code>$HOME/.bashrc</code>, +<code>$HOME/.profile</code>, or equivalent). The settings might look +something like this: +</p> + +<pre> +export GOROOT=$HOME/go +export GOARCH=386 +export GOOS=linux +</pre> diff --git a/doc/logo-153x55.png b/doc/logo-153x55.png Binary files differnew file mode 100644 index 000000000..4a2446ce7 --- /dev/null +++ b/doc/logo-153x55.png diff --git a/doc/logo.png b/doc/logo.png Binary files differnew file mode 100644 index 000000000..076ce398e --- /dev/null +++ b/doc/logo.png diff --git a/doc/makehtml b/doc/makehtml new file mode 100755 index 000000000..2418c68fa --- /dev/null +++ b/doc/makehtml @@ -0,0 +1,17 @@ +#!/bin/sh +# Copyright 2009 The Go Authors. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +set -e + +TMPL=${1:-go_tutorial.tmpl} # input file +HTML=$(basename $TMPL .tmpl).html # output file (basename) + +if ! test -w $HTML +then + echo 1>&2 makehtml: cannot open $HTML for write + exit 1 +fi + +make && ./tmpltohtml $TMPL > $HTML diff --git a/doc/play_overlay.png b/doc/play_overlay.png Binary files differnew file mode 100644 index 000000000..20ef7f399 --- /dev/null +++ b/doc/play_overlay.png diff --git a/doc/playground.html b/doc/playground.html new file mode 100644 index 000000000..01d3adc9c --- /dev/null +++ b/doc/playground.html @@ -0,0 +1,27 @@ +<!-- About the Go Playground --> + +<div class="left-column"> +<p> +The Go Playground is a web service that runs on +<a href="http://golang.org/">golang.org</a>'s servers. +The service receives a Go program, compiles, links, and runs the program inside +a sandbox, then returns the output. +</p> + +<p> +There are limitations to the programs that can be run in the Playground. +They must be single-threaded (but they may use many goroutines). +There are also limits on execution time, and CPU and memory usage. +The Playground can access only a subset of the standard library +(notably absent are network and file system access). +Therefore, the only communication a Playground program has to the outside world +is via standard output. +</div> + +<div class="right-column"> +<script src="http://www.google.com/jsapi" type="text/javascript"></script> +<div id="playground" class="small"></div> +<script src="/doc/play/playground.js"></script> +</div> + +<div class="end-columns"></div> diff --git a/doc/popups.js b/doc/popups.js new file mode 100644 index 000000000..23ccc8c75 --- /dev/null +++ b/doc/popups.js @@ -0,0 +1,24 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +function godocs_bindPopups(data) { + + $('#content span').bind('mouseenter', function() { + var id = $(this).attr('id'); + //var txt = $(this).text(); + if (typeof data[id] == 'undefined') + return; + var content = data[id]; + + var $el = $('.popup', this); + if (!$el.length) { // create it + $el = $('<div class="popup"></div>'); + $el.prependTo(this).css($(this).offset()).text(content); + } + }); + $('#content span').bind('mouseleave', function() { + $('.popup', this).remove(); + }); + +} diff --git a/doc/progs/cat.go b/doc/progs/cat.go new file mode 100644 index 000000000..9f0b8d4a3 --- /dev/null +++ b/doc/progs/cat.go @@ -0,0 +1,47 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "./file" + "flag" + "fmt" + "os" +) + +func cat(f *file.File) { + const NBUF = 512 + var buf [NBUF]byte + for { + switch nr, er := f.Read(buf[:]); true { + case nr < 0: + fmt.Fprintf(os.Stderr, "cat: error reading from %s: %s\n", f.String(), er.String()) + os.Exit(1) + case nr == 0: // EOF + return + case nr > 0: + if nw, ew := file.Stdout.Write(buf[0:nr]); nw != nr { + fmt.Fprintf(os.Stderr, "cat: error writing from %s: %s\n", f.String(), ew.String()) + os.Exit(1) + } + } + } +} + +func main() { + flag.Parse() // Scans the arg list and sets up flags + if flag.NArg() == 0 { + cat(file.Stdin) + } + for i := 0; i < flag.NArg(); i++ { + f, err := file.Open(flag.Arg(i)) + if f == nil { + fmt.Fprintf(os.Stderr, "cat: can't open %s: error %s\n", flag.Arg(i), err) + os.Exit(1) + } + cat(f) + f.Close() + } +} diff --git a/doc/progs/cat_rot13.go b/doc/progs/cat_rot13.go new file mode 100644 index 000000000..0eefe7cfc --- /dev/null +++ b/doc/progs/cat_rot13.go @@ -0,0 +1,90 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "./file" + "flag" + "fmt" + "os" +) + +var rot13Flag = flag.Bool("rot13", false, "rot13 the input") + +func rot13(b byte) byte { + if 'a' <= b && b <= 'z' { + b = 'a' + ((b-'a')+13)%26 + } + if 'A' <= b && b <= 'Z' { + b = 'A' + ((b-'A')+13)%26 + } + return b +} + +type reader interface { + Read(b []byte) (ret int, err os.Error) + String() string +} + +type rotate13 struct { + source reader +} + +func newRotate13(source reader) *rotate13 { + return &rotate13{source} +} + +func (r13 *rotate13) Read(b []byte) (ret int, err os.Error) { + r, e := r13.source.Read(b) + for i := 0; i < r; i++ { + b[i] = rot13(b[i]) + } + return r, e +} + +func (r13 *rotate13) String() string { + return r13.source.String() +} +// end of rotate13 implementation + +func cat(r reader) { + const NBUF = 512 + var buf [NBUF]byte + + if *rot13Flag { + r = newRotate13(r) + } + for { + switch nr, er := r.Read(buf[:]); { + case nr < 0: + fmt.Fprintf(os.Stderr, "cat: error reading from %s: %s\n", r.String(), er.String()) + os.Exit(1) + case nr == 0: // EOF + return + case nr > 0: + nw, ew := file.Stdout.Write(buf[0:nr]) + if nw != nr { + fmt.Fprintf(os.Stderr, "cat: error writing from %s: %s\n", r.String(), ew.String()) + os.Exit(1) + } + } + } +} + +func main() { + flag.Parse() // Scans the arg list and sets up flags + if flag.NArg() == 0 { + cat(file.Stdin) + } + for i := 0; i < flag.NArg(); i++ { + f, err := file.Open(flag.Arg(i)) + if f == nil { + fmt.Fprintf(os.Stderr, "cat: can't open %s: error %s\n", flag.Arg(i), err) + os.Exit(1) + } + cat(f) + f.Close() + } +} diff --git a/doc/progs/echo.go b/doc/progs/echo.go new file mode 100644 index 000000000..3260edd74 --- /dev/null +++ b/doc/progs/echo.go @@ -0,0 +1,32 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "os" + "flag" // command line option parser +) + +var omitNewline = flag.Bool("n", false, "don't print final newline") + +const ( + Space = " " + Newline = "\n" +) + +func main() { + flag.Parse() // Scans the arg list and sets up flags + var s string = "" + for i := 0; i < flag.NArg(); i++ { + if i > 0 { + s += Space + } + s += flag.Arg(i) + } + if !*omitNewline { + s += Newline + } + os.Stdout.WriteString(s) +} diff --git a/doc/progs/file.go b/doc/progs/file.go new file mode 100644 index 000000000..2875ce73a --- /dev/null +++ b/doc/progs/file.go @@ -0,0 +1,89 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package file + +import ( + "os" + "syscall" +) + +type File struct { + fd int // file descriptor number + name string // file name at Open time +} + +func newFile(fd int, name string) *File { + if fd < 0 { + return nil + } + return &File{fd, name} +} + +var ( + Stdin = newFile(syscall.Stdin, "/dev/stdin") + Stdout = newFile(syscall.Stdout, "/dev/stdout") + Stderr = newFile(syscall.Stderr, "/dev/stderr") +) + +func OpenFile(name string, mode int, perm uint32) (file *File, err os.Error) { + r, e := syscall.Open(name, mode, perm) + if e != 0 { + err = os.Errno(e) + } + return newFile(r, name), err +} + +const ( + O_RDONLY = syscall.O_RDONLY + O_RDWR = syscall.O_RDWR + O_CREATE = syscall.O_CREAT + O_TRUNC = syscall.O_TRUNC +) + +func Open(name string) (file *File, err os.Error) { + return OpenFile(name, O_RDONLY, 0) +} + +func Create(name string) (file *File, err os.Error) { + return OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0666) +} + +func (file *File) Close() os.Error { + if file == nil { + return os.EINVAL + } + e := syscall.Close(file.fd) + file.fd = -1 // so it can't be closed again + if e != 0 { + return os.Errno(e) + } + return nil +} + +func (file *File) Read(b []byte) (ret int, err os.Error) { + if file == nil { + return -1, os.EINVAL + } + r, e := syscall.Read(file.fd, b) + if e != 0 { + err = os.Errno(e) + } + return int(r), err +} + +func (file *File) Write(b []byte) (ret int, err os.Error) { + if file == nil { + return -1, os.EINVAL + } + r, e := syscall.Write(file.fd, b) + if e != 0 { + err = os.Errno(e) + } + return int(r), err +} + +func (file *File) String() string { + return file.name +} diff --git a/doc/progs/file_windows.go b/doc/progs/file_windows.go new file mode 100644 index 000000000..03003a3f7 --- /dev/null +++ b/doc/progs/file_windows.go @@ -0,0 +1,89 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package file + +import ( + "os" + "syscall" +) + +type File struct { + fd syscall.Handle // file descriptor number + name string // file name at Open time +} + +func newFile(fd syscall.Handle, name string) *File { + if fd < 0 { + return nil + } + return &File{fd, name} +} + +var ( + Stdin = newFile(syscall.Stdin, "/dev/stdin") + Stdout = newFile(syscall.Stdout, "/dev/stdout") + Stderr = newFile(syscall.Stderr, "/dev/stderr") +) + +func OpenFile(name string, mode int, perm uint32) (file *File, err os.Error) { + r, e := syscall.Open(name, mode, perm) + if e != 0 { + err = os.Errno(e) + } + return newFile(r, name), err +} + +const ( + O_RDONLY = syscall.O_RDONLY + O_RDWR = syscall.O_RDWR + O_CREATE = syscall.O_CREAT + O_TRUNC = syscall.O_TRUNC +) + +func Open(name string) (file *File, err os.Error) { + return OpenFile(name, O_RDONLY, 0) +} + +func Create(name string) (file *File, err os.Error) { + return OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0666) +} + +func (file *File) Close() os.Error { + if file == nil { + return os.EINVAL + } + e := syscall.Close(file.fd) + file.fd = syscall.InvalidHandle // so it can't be closed again + if e != 0 { + return os.Errno(e) + } + return nil +} + +func (file *File) Read(b []byte) (ret int, err os.Error) { + if file == nil { + return -1, os.EINVAL + } + r, e := syscall.Read(file.fd, b) + if e != 0 { + err = os.Errno(e) + } + return int(r), err +} + +func (file *File) Write(b []byte) (ret int, err os.Error) { + if file == nil { + return -1, os.EINVAL + } + r, e := syscall.Write(file.fd, b) + if e != 0 { + err = os.Errno(e) + } + return int(r), err +} + +func (file *File) String() string { + return file.name +} diff --git a/doc/progs/helloworld.go b/doc/progs/helloworld.go new file mode 100644 index 000000000..8185038d9 --- /dev/null +++ b/doc/progs/helloworld.go @@ -0,0 +1,11 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import fmt "fmt" // Package implementing formatted I/O. + +func main() { + fmt.Printf("Hello, world; or Καλημέρα κόσμε; or こんにちは 世界\n") +} diff --git a/doc/progs/helloworld3.go b/doc/progs/helloworld3.go new file mode 100644 index 000000000..2011513b7 --- /dev/null +++ b/doc/progs/helloworld3.go @@ -0,0 +1,21 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "./file" + "fmt" + "os" +) + +func main() { + hello := []byte("hello, world\n") + file.Stdout.Write(hello) + f, err := file.Open("/does/not/exist") + if f == nil { + fmt.Printf("can't open file; err=%s\n", err.String()) + os.Exit(1) + } +} diff --git a/doc/progs/print.go b/doc/progs/print.go new file mode 100644 index 000000000..8f44ba8c6 --- /dev/null +++ b/doc/progs/print.go @@ -0,0 +1,23 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import "fmt" + +func main() { + var u64 uint64 = 1<<64 - 1 + fmt.Printf("%d %d\n", u64, int64(u64)) + + // harder stuff + type T struct { + a int + b string + } + t := T{77, "Sunset Strip"} + a := []int{1, 2, 3, 4} + fmt.Printf("%v %v %v\n", u64, t, a) + fmt.Print(u64, " ", t, " ", a, "\n") + fmt.Println(u64, t, a) +} diff --git a/doc/progs/print_string.go b/doc/progs/print_string.go new file mode 100644 index 000000000..46ab1d91a --- /dev/null +++ b/doc/progs/print_string.go @@ -0,0 +1,21 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import "fmt" + +type testType struct { + a int + b string +} + +func (t *testType) String() string { + return fmt.Sprint(t.a) + " " + t.b +} + +func main() { + t := &testType{77, "Sunset Strip"} + fmt.Println(t) +} diff --git a/doc/progs/run b/doc/progs/run new file mode 100755 index 000000000..81781c9d2 --- /dev/null +++ b/doc/progs/run @@ -0,0 +1,85 @@ +#!/usr/bin/env bash +# Copyright 2009 The Go Authors. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +set -e + +eval $(gomake --no-print-directory -f ../../src/Make.inc go-env) + +if [ -z "$O" ]; then + echo 'missing $O - maybe no Make.$GOARCH?' 1>&2 + exit 1 +fi + +rm -f *.$O + +if [ "$GOOS" = "windows" ];then + $GC -o file.8 file_windows.go +else + $GC file.go +fi + +for i in \ + helloworld.go \ + helloworld3.go \ + echo.go \ + cat.go \ + cat_rot13.go \ + sum.go \ + sort.go \ + sortmain.go \ + print.go \ + print_string.go \ + sieve.go \ + sieve1.go \ + server1.go \ + strings.go \ +; do + $GC $i +done + +function testit { + $LD $1.$O + x=$(echo $(./$O.out $2 2>&1)) # extra echo canonicalizes + if [ "$x" != "$3" ] + then + echo $1 failed: '"'$x'"' is not '"'$3'"' + fi +} + +function testitpipe { + $LD $1.$O + x=$(echo $(./$O.out | $2 2>&1)) # extra echo canonicalizes + if [ "$x" != "$3" ] + then + echo $1 failed: '"'$x'"' is not '"'$3'"' + fi +} + + +testit helloworld "" "Hello, world; or Καλημέρα κόσμε; or こんにちは 世界" +testit helloworld3 "" "hello, world can't open file; err=no such file or directory" +testit echo "hello, world" "hello, world" +testit sum "" "6" +testit strings "" "" + +alphabet=abcdefghijklmnopqrstuvwxyz +rot13=nopqrstuvwxyzabcdefghijklm +echo $alphabet | testit cat "" $alphabet +echo $alphabet | testit cat_rot13 "--rot13" $rot13 +echo $rot13 | testit cat_rot13 "--rot13" $alphabet + +testit sortmain "" "Sunday Monday Tuesday Wednesday Thursday Friday Saturday" + +testit print "" "18446744073709551615 -1 18446744073709551615 {77 Sunset Strip} [1 2 3 4] 18446744073709551615 {77 Sunset Strip} [1 2 3 4] 18446744073709551615 {77 Sunset Strip} [1 2 3 4]" +testit print_string "" "77 Sunset Strip" + +testitpipe sieve "sed 10q" "2 3 5 7 11 13 17 19 23 29" +testitpipe sieve "sed 10q" "2 3 5 7 11 13 17 19 23 29" + +# server hangs; don't run it, just compile it +$GC server.go +testit server1 "" "" + +rm -f $O.out *.$O diff --git a/doc/progs/server.go b/doc/progs/server.go new file mode 100644 index 000000000..b498b53a6 --- /dev/null +++ b/doc/progs/server.go @@ -0,0 +1,51 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import "fmt" + +type request struct { + a, b int + replyc chan int +} + +type binOp func(a, b int) int + +func run(op binOp, req *request) { + reply := op(req.a, req.b) + req.replyc <- reply +} + +func server(op binOp, service chan *request) { + for { + req := <-service + go run(op, req) // don't wait for it + } +} + +func startServer(op binOp) chan *request { + req := make(chan *request) + go server(op, req) + return req +} + +func main() { + adder := startServer(func(a, b int) int { return a + b }) + const N = 100 + var reqs [N]request + for i := 0; i < N; i++ { + req := &reqs[i] + req.a = i + req.b = i + N + req.replyc = make(chan int) + adder <- req + } + for i := N - 1; i >= 0; i-- { // doesn't matter what order + if <-reqs[i].replyc != N+2*i { + fmt.Println("fail at", i) + } + } + fmt.Println("done") +} diff --git a/doc/progs/server1.go b/doc/progs/server1.go new file mode 100644 index 000000000..a4093924b --- /dev/null +++ b/doc/progs/server1.go @@ -0,0 +1,56 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import "fmt" + +type request struct { + a, b int + replyc chan int +} + +type binOp func(a, b int) int + +func run(op binOp, req *request) { + reply := op(req.a, req.b) + req.replyc <- reply +} + +func server(op binOp, service chan *request, quit chan bool) { + for { + select { + case req := <-service: + go run(op, req) // don't wait for it + case <-quit: + return + } + } +} + +func startServer(op binOp) (service chan *request, quit chan bool) { + service = make(chan *request) + quit = make(chan bool) + go server(op, service, quit) + return service, quit +} + +func main() { + adder, quit := startServer(func(a, b int) int { return a + b }) + const N = 100 + var reqs [N]request + for i := 0; i < N; i++ { + req := &reqs[i] + req.a = i + req.b = i + N + req.replyc = make(chan int) + adder <- req + } + for i := N - 1; i >= 0; i-- { // doesn't matter what order + if <-reqs[i].replyc != N+2*i { + fmt.Println("fail at", i) + } + } + quit <- true +} diff --git a/doc/progs/sieve.go b/doc/progs/sieve.go new file mode 100644 index 000000000..b31530981 --- /dev/null +++ b/doc/progs/sieve.go @@ -0,0 +1,38 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import "fmt" + +// Send the sequence 2, 3, 4, ... to channel 'ch'. +func generate(ch chan int) { + for i := 2; ; i++ { + ch <- i // Send 'i' to channel 'ch'. + } +} + +// Copy the values from channel 'in' to channel 'out', +// removing those divisible by 'prime'. +func filter(in, out chan int, prime int) { + for { + i := <-in // Receive value of new variable 'i' from 'in'. + if i%prime != 0 { + out <- i // Send 'i' to channel 'out'. + } + } +} + +// The prime sieve: Daisy-chain filter processes together. +func main() { + ch := make(chan int) // Create a new channel. + go generate(ch) // Start generate() as a goroutine. + for i := 0; i < 100; i++ { // Print the first hundred primes. + prime := <-ch + fmt.Println(prime) + ch1 := make(chan int) + go filter(ch, ch1, prime) + ch = ch1 + } +} diff --git a/doc/progs/sieve1.go b/doc/progs/sieve1.go new file mode 100644 index 000000000..e1411a334 --- /dev/null +++ b/doc/progs/sieve1.go @@ -0,0 +1,51 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import "fmt" + +// Send the sequence 2, 3, 4, ... to returned channel +func generate() chan int { + ch := make(chan int) + go func() { + for i := 2; ; i++ { + ch <- i + } + }() + return ch +} + +// Filter out input values divisible by 'prime', send rest to returned channel +func filter(in chan int, prime int) chan int { + out := make(chan int) + go func() { + for { + if i := <-in; i%prime != 0 { + out <- i + } + } + }() + return out +} + +func sieve() chan int { + out := make(chan int) + go func() { + ch := generate() + for { + prime := <-ch + out <- prime + ch = filter(ch, prime) + } + }() + return out +} + +func main() { + primes := sieve() + for i := 0; i < 100; i++ { // Print the first hundred primes. + fmt.Println(<-primes) + } +} diff --git a/doc/progs/sort.go b/doc/progs/sort.go new file mode 100644 index 000000000..894693f0d --- /dev/null +++ b/doc/progs/sort.go @@ -0,0 +1,59 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package sort + +type Interface interface { + Len() int + Less(i, j int) bool + Swap(i, j int) +} + +func Sort(data Interface) { + for i := 1; i < data.Len(); i++ { + for j := i; j > 0 && data.Less(j, j-1); j-- { + data.Swap(j, j-1) + } + } +} + +func IsSorted(data Interface) bool { + n := data.Len() + for i := n - 1; i > 0; i-- { + if data.Less(i, i-1) { + return false + } + } + return true +} + +// Convenience types for common cases + +type IntSlice []int + +func (p IntSlice) Len() int { return len(p) } +func (p IntSlice) Less(i, j int) bool { return p[i] < p[j] } +func (p IntSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } + +type Float64Slice []float64 + +func (p Float64Slice) Len() int { return len(p) } +func (p Float64Slice) Less(i, j int) bool { return p[i] < p[j] } +func (p Float64Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } + +type StringSlice []string + +func (p StringSlice) Len() int { return len(p) } +func (p StringSlice) Less(i, j int) bool { return p[i] < p[j] } +func (p StringSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } + +// Convenience wrappers for common cases + +func SortInts(a []int) { Sort(IntSlice(a)) } +func SortFloat64s(a []float64) { Sort(Float64Slice(a)) } +func SortStrings(a []string) { Sort(StringSlice(a)) } + +func IntsAreSorted(a []int) bool { return IsSorted(IntSlice(a)) } +func Float64sAreSorted(a []float64) bool { return IsSorted(Float64Slice(a)) } +func StringsAreSorted(a []string) bool { return IsSorted(StringSlice(a)) } diff --git a/doc/progs/sortmain.go b/doc/progs/sortmain.go new file mode 100644 index 000000000..c1babb01f --- /dev/null +++ b/doc/progs/sortmain.go @@ -0,0 +1,69 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "fmt" + "./sort" +) + +func ints() { + data := []int{74, 59, 238, -784, 9845, 959, 905, 0, 0, 42, 7586, -5467984, 7586} + a := sort.IntSlice(data) + sort.Sort(a) + if !sort.IsSorted(a) { + panic("fail") + } +} + +func strings() { + data := []string{"monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"} + a := sort.StringSlice(data) + sort.Sort(a) + if !sort.IsSorted(a) { + panic("fail") + } +} + +type day struct { + num int + shortName string + longName string +} + +type dayArray struct { + data []*day +} + +func (p *dayArray) Len() int { return len(p.data) } +func (p *dayArray) Less(i, j int) bool { return p.data[i].num < p.data[j].num } +func (p *dayArray) Swap(i, j int) { p.data[i], p.data[j] = p.data[j], p.data[i] } + +func days() { + Sunday := day{0, "SUN", "Sunday"} + Monday := day{1, "MON", "Monday"} + Tuesday := day{2, "TUE", "Tuesday"} + Wednesday := day{3, "WED", "Wednesday"} + Thursday := day{4, "THU", "Thursday"} + Friday := day{5, "FRI", "Friday"} + Saturday := day{6, "SAT", "Saturday"} + data := []*day{&Tuesday, &Thursday, &Wednesday, &Sunday, &Monday, &Friday, &Saturday} + a := dayArray{data} + sort.Sort(&a) + if !sort.IsSorted(&a) { + panic("fail") + } + for _, d := range data { + fmt.Printf("%s ", d.longName) + } + fmt.Printf("\n") +} + + +func main() { + ints() + strings() + days() +} diff --git a/doc/progs/strings.go b/doc/progs/strings.go new file mode 100644 index 000000000..e6739b385 --- /dev/null +++ b/doc/progs/strings.go @@ -0,0 +1,17 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import "os" + +func main() { + s := "hello" + if s[1] != 'e' { + os.Exit(1) + } + s = "good bye" + var p *string = &s + *p = "ciao" +} diff --git a/doc/progs/sum.go b/doc/progs/sum.go new file mode 100644 index 000000000..e022195ed --- /dev/null +++ b/doc/progs/sum.go @@ -0,0 +1,20 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import "fmt" + +func sum(a []int) int { // returns an int + s := 0 + for i := 0; i < len(a); i++ { + s += a[i] + } + return s +} + +func main() { + s := sum([3]int{1, 2, 3}[:]) // a slice of the array is passed to sum + fmt.Print(s, "\n") +} diff --git a/doc/root.html b/doc/root.html new file mode 100644 index 000000000..8d76928c8 --- /dev/null +++ b/doc/root.html @@ -0,0 +1,98 @@ +<link rel="stylesheet" type="text/css" href="/doc/frontpage.css"> + +<script src="http://www.google.com/jsapi" type="text/javascript"></script> +<script type="text/javascript"> +function loadFeed() { + var url = "http://blog.golang.org/feeds/posts/default"; + var divId = "blogFeed"; + var feed = new google.feeds.Feed(url); + feed.setNumEntries(4) + feed.load(function (result) { + var container = document.getElementById(divId) + if (result.error) { + container.innerHTML = "Error loading feed."; + return; + } + container.innerHTML = ""; + var entries = result.feed.entries; + for (var i=0; i<entries.length; i++) { + var li = document.createElement("li"); + var a = document.createElement("a"); + a.setAttribute("href", entries[i].link); + var span_title = document.createElement("span"); + span_title.appendChild(document.createTextNode(entries[i].title)); + span_title.className = "title"; + a.appendChild(span_title); + li.appendChild(a); + var span_date = document.createElement("span"); + span_date.appendChild(document.createTextNode(entries[i].publishedDate.substr(0, 11))); + span_date.className = "date"; + a.appendChild(span_date); + container.appendChild(li); + } + }); +} +google.load("feeds", "1"); +google.setOnLoadCallback(loadFeed); +</script> + + <div id="frontpage"> + <div class="left-column"> + <p style="margin-top: 0;"> + The Go programming language is an open source project to make + programmers more productive. Go is expressive, concise, clean, + and efficient. Its concurrency mechanisms make it easy to write + programs that get the most out of multicore and networked machines, + while its novel type system enables flexible and modular program + construction. Go compiles quickly to machine code yet has the + convenience of garbage collection and the power of run-time reflection. + It's a fast, statically typed, compiled language that feels like a + dynamically typed, interpreted language. + </p> + <h2>Check it out!</h2> + <p> + <div class="how">[<a href="/doc/playground.html">How does this work?</a>]</div> + <a href="/doc/install.html">Install Go now</a>, or try it right here in your browser:</p> + <div id="playground" class="small"></div> + <script src="/doc/play/playground.js"></script> + </div> + <div class="right-column"> + <div id="content-rotating"> + <div id="content-videos"> + <h2>Go Videos <span class="more">| <a href="/doc/docs.html#videos_talks">More...</a></span></h2> + <a class="video" href="http://www.youtube.com/watch?v=-i0hat7pdpk"><img src="/doc/play_overlay.png" class="thumbnail _005" /> <span class="caption title">“Writing Web Apps in Go”</span> <span class="caption description">Google I/O 2011</span></a> + </div> + <h2>Go Blog <span class="more">| <a href="http://blog.golang.org/">More...</a></span></h2> + <div id="content-blog"> + <ul id="blogFeed"> + </ul> + </div> + </div> + <h2>Quick Links</h2> + <div id="resources"> + <div id="resources-users"> + <h3>For newcomers:</h3> + <ul> + <li><a href="/doc/install.html">Getting Started</a></li> + <li><a href="/doc/go_tutorial.html">Tutorial</a></li> + <li><a href="/doc/effective_go.html">Effective Go</a></li> + <li><a href="/doc/go_faq.html">Go FAQ</a></li> + <li><a href="/doc/docs.html">Other Documentation</a></li> + <li><a href="http://code.google.com/appengine/docs/go/">Go for Google App Engine</a> <sup class="new">New!</sup></li> + </ul> + </div> + <div id="resources-contributors" > + <h3>For developers:</h3> + <ul> + <li><a href="http://godashboard.appspot.com/package">Package Dashboard</a></li> + <li><a href="http://code.google.com/p/go/issues">Issue Tracker</a></li> + <li><a href="http://godashboard.appspot.com/">Build Status</a></li> + <li><a href="http://code.google.com/p/go/source/browse/">Go Source</a> [<a href="http://code.google.com/p/go/source/list">changes</a>]</li> + <li><a href="/pkg/">Package Reference</a></li> + <li><a href="/doc/go_spec.html">Language Specification</a></li> + </ul> + </div> + </div> + </div> + <div class="end-columns"></div> + </div> diff --git a/doc/sieve.gif b/doc/sieve.gif Binary files differnew file mode 100644 index 000000000..8018ae225 --- /dev/null +++ b/doc/sieve.gif diff --git a/doc/talks/go_talk-20100112.html b/doc/talks/go_talk-20100112.html new file mode 100644 index 000000000..2e3643512 --- /dev/null +++ b/doc/talks/go_talk-20100112.html @@ -0,0 +1,411 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> +<title>Go (January 12, 2010)</title> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> +<meta name="font-size-adjustment" content="-1" /> +<link rel="stylesheet" href="slidy.css" + type="text/css" media="screen, projection, print" /> +<script src="slidy.js" type="text/javascript"> +</script> +</head> +<body> +<!-- this defines the slide background --> + +<div class="background"> + + <div class="header"> + <!-- sized and colored via CSS --> + </div> + + <div class="footer"></div> + </div> + +<div class="slide titlepage"> +<div style="height: 135px; width: 480px; overflow: hidden; position: fixed; top: auto; bottom: 10px; left: auto; right: 0; "> +<img src="../gordon/bumper480x270.png" style="margin: -135px 0 0 0;"/> +</div> +<!-- <img src="google.png" style="position: fixed; top: auto; bottom: 30px; left: 20px; right: auto;"/> --> +<br/> +<img src="../go-logo-white.png"> +<br/> +<br/> +<h1 style="padding-right: 0pt; margin-right: 0pt; color: #0066cc; font-size: 250%; border-bottom: 0px;">The Go Programming Language</h1> +<div style="color: #ffcc00;"> +<h2>Russ Cox</h2> +<!-- <h3><i>rsc@google.com</i></h3> --> +<br/> +<h3>Stanford University<br/><br/>January 12, 2010</h3> +</div> +</div> + +<div class="slide"> + <h1>Go</h1> + + <h2>New</h2> + <h2>Experimental</h2> + <h2>Concurrent</h2> + <h2>Garbage-collected</h2> + <h2>Systems</h2> + <h2>Language</h2> +</div> + +<div class="slide"> + <h1>Hello, world</h1> +<pre> +package main + +import "fmt" + +func main() { + fmt.Printf("Hello, 世界\n") +} +</pre> +</div> + +<div class="slide"> + <h1>History</h1> + + <h2>Design started in late 2007.</h2> + <h2>Implementation starting to work mid-2008.</h2> + <h2>Released as an open source project in November 2009.</h2> + <h2>Work continues.<h2> + <h2>Robert Griesemer, Ken Thompson, Rob Pike, Ian Lance Taylor, Russ Cox, many others</h2> +</div> + +<div class="slide"> + <h1>Why?</h1> + + <h2>Go fast!</h2> + <h2>Make programming fun again.</h2> +</div> + +<div class="slide"> + <h1>Why isn't programming fun?</h1> + + <div class="incremental"> + <h2>Compiled, statically-typed languages (C, C++, Java) require too much typing and too much typing:</h2> + + <ul> + <li>verbose, lots of repetition</li> + <li>too much focus on type hierarchy</li> + <li>types get in the way as much as they help</li> + <li>compiles take far too long</li> + </ul> + </div> + + <div class="incremental"> + <h2>Dynamic languages (Python, JavaScript) fix these problems (no more types, no more compiler) but introduce others:</h2> + + <ul> + <li>errors at run time that should be caught statically</li> + <li>no compilation means slow code</li> + </ul> + </div> + + <h2 class="incremental">Can we combine the best of both?</h2> +</div> + +<div class="slide"> + <h1>Go</h1> + + <h2>Make the language fast.</h2> + <h2>Make the tools fast.</h2> +</div> + +<div class="slide"> + <h1>Go Approach: Static Types</h1> + + <h2>Static types, but declarations can infer type from expression:</h2> + +<pre> +var one, hi = 1, "hello" + +var double = func(x int) int { return x*2 } +</pre> + + <h2>Not full Hindley-Milner type inference.</h2> +</div> + + +<div class="slide"> + <h1>Go Approach: Methods</h1> + + <h2>Methods can be defined on any type.</h2> + +<pre> +type Point struct { + X, Y float64 +} + +func (p Point) Abs() float64 { + return math.Sqrt(p.X*p.X + p.Y*p.Y) +} +</pre> +</div> + +<div class="slide"> + <h1>Go Approach: Methods</h1> + + <h2>Methods can be defined on any type.</h2> + +<pre> +type MyFloat float64 + +func (f MyFloat) Abs() float64 { + v := float64(f) + if v < 0 { + v = -v + } + return v +} +</pre> +</div> + +<div class="slide"> + <h1>Go Approach: Abstract Types</h1> + + <h2>An interface type lists a set of methods. Any value with those methods satisfies the interface.</h2> + +<pre> +type Abser interface { + Abs() float64 +} + +func AbsPrinter(a Abser) +</pre> + + <h2>Can use Point or MyFloat (or ...):</h2> + +<pre> +p := Point{3, 4} +AbsPrinter(p) + +f := MyFloat(-10) +AbsPrinter(f) +</pre> + + <h2>Notice that Point never declared that it implements Abser. It just does. Same with MyFloat.</h2> +</div> + +<div class="slide"> + <h1>Go Approach: Packages</h1> + + <h2>A Go program comprises one or more packages.</h2> + <h2>Each package is one or more source files compiled and imported as a unit.</h2> +<pre> +package draw + +type Point struct { + X, Y int +} +</pre> + +<pre> +package main + +import "draw" + +var p draw.Point +</pre> +</div> + +<div class="slide"> + <h1>Go Approach: Visibility</h1> + + <h2>Inside a package, all locally defined names are visible in all source files.</h2> + + <h2>When imported, only the upper case names are visible.</h2> + +<pre> +package draw + +type <span style="color: black;">Point</span> struct { + <span style="color: black;">X</span>, <span style="color: black;">Y</span> int + dist float64 +} + +type cache map[Point] float64 +</pre> + +<h2>Clients that <code>import "draw"</code> can use the black names only.</h2> + +<h2>“Shift is the new <code>public</code>.”</h2> +</div> + +<div class="slide"> + <h1>Go Approach: Concurrency</h1> + + <h2>Cheap to create a new flow of control (goroutine):</h2> + +<pre> +func main() { + go expensiveComputation(x, y, z) + anotherExpensiveComputation(a, b, c) +} +</pre> + + <h2>Two expensive computations in parallel.</h2> +</div> + +<div class="slide"> + <h1>Go Approach: Synchronization</h1> + + <h2>Use explicit messages to communicate and synchronize.</h2> + +<pre> +func computeAndSend(ch chan int, x, y, z int) { + ch <- expensiveComputation(x, y, z) +} + +func main() { + ch := make(chan int) + go computeAndSend(ch, x, y, z) + v2 := anotherExpensiveComputation(a, b, c) + v1 := <-ch + fmt.Println(v1, v2) +} +</pre> + <h2>Notice communication of result in addition to synchronization.</h2> +</div> + +<div class="slide"> + <h1>Go Fast: Language</h1> + + <h2 class="incremental">Static types: enough to compile well, but inferred much of the time.</h2> + + <h2 class="incremental">Methods: on any type, orthogonal to type system.</h2> + + <h2 class="incremental">Abstract types: interface values, relations inferred statically.</h2> + + <h2 class="incremental">Visibility: inferred from case of name.</h2> + + <h2 class="incremental">Concurrency: lightweight way to start new thread of control.</h2> + + <h2 class="incremental">Synchronization: explicit, easy message passing.</h2> + + <br/> + + <h2 class="incremental">Lightweight feel of a scripting language but compiled.</h2> +</div> + +<div class="slide"> + <h1>Compile fast</h1> + + <div class="incremental"> + <h2>Observation: much of the compile time for a source file is spent processing + other, often unrelated files.</h2> + + <h2>In C: <code>a.c</code> includes <code>b.h</code>, which includes <code>c.h</code>, which includes <code>d.h</code>. + </h2> + + <h2>Except that it's more often a tree instead of a chain.</h2> + + <h2>On my Mac (OS X 10.5.8, gcc 4.0.1):</h2> + <ul> + <li>C: <code>#include <stdio.h></code> reads 360 lines from 9 files. + <li>C++: <code>#include <iostream></code> reads 25,326 lines from 131 files. + <li>Objective C: <code>#include <Carbon/Carbon.h></code> reads 124,730 lines from 689 files. + </ul> + + <h2>And we haven't done any real work yet!</h2> + + <h2>Same story in Java, Python, but reading binaries instead of source files.</h2> + </div> +</div> + +<div class="slide"> + <h1>Implementation: Summarize Dependencies</h1> + +<pre> +package gui + +import "draw" + +type Mouse struct { + Loc draw.Point + Buttons uint +} +</pre> + <h2>Compiled form of <code>gui</code> summarizes the necessary part of <code>draw</code> (just <code>Point</code>).</h2> + +</div> + +<div class="slide"> + <h1>Implementation: Summarize Dependencies</h1> + + <h2>Compiled form of <code>gui</code> summarizes the necessary part of <code>draw</code> (just <code>Point</code>). Pseudo-object:</h2> + +<pre> +package gui +type draw.Point struct { + X, Y int +} +type gui.Mouse struct { + Loc draw.Point + Buttons uint +} +</pre> + + <h2>A file that imports <code>gui</code> compiles without consulting <code>draw</code> or its dependencies.</h2> + + <h2>In Go: <code>import "fmt"</code> reads <i>one</i> file: 184 lines summarizing types from 7 packages.</h2> + + <h2>Tiny effect in this program but can be exponential in large programs.</h2> +</div> + +<div class="slide"> + <h1>Compilation Demo</h1> + + <h2>Build all standard Go packages: ~120,000 lines of code.</h2> +</div> + +<div class="slide"> + <h1>Go Status</h1> + + <div class="incremental"> + <div> + <h2>Open source:</h2> + <ul> + <li>released on November 10, 2009 + <li>regular releases (~ weekly) + <li>all development done in public Mercurial repository + <li>outside contributions welcome + </ul> + </div> + + <div> + <h2>Portable:</h2> + <ul> + <li>FreeBSD, Linux, OS X (x86, x86-64) + <li>(in progress) Linux arm, Native Client x86, Windows x86. + </ul> + </div> + + <div> + <h2>Still in progress, experimental. Yet to come:</h2> + <ul> + <li>mature garbage collector + <li>generics? + <li>exceptions? + <li>unions or sum types? + </ul> + </div> + </div> + +</div> + +<div class="slide titlepage"> + <h1>Questions?</h1> + <br><br> + <center> + <img src="../gordon/bumper640x360.png"> + </center> + <br><br> + <div style="color: #ffcc00;"> + <!-- <h3><i>rsc@google.com</i></h3> --> + </div> +</div> + +</body></html> diff --git a/doc/talks/go_talk-20100121.html b/doc/talks/go_talk-20100121.html new file mode 100644 index 000000000..d5e4bc66f --- /dev/null +++ b/doc/talks/go_talk-20100121.html @@ -0,0 +1,453 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> +<title>Go, Networked (January 21, 2010)</title> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> +<meta name="font-size-adjustment" content="-1" /> +<link rel="stylesheet" href="slidy.css" + type="text/css" media="screen, projection, print" /> +<script src="slidy.js" type="text/javascript"> +</script> +</head> +<body> +<!-- this defines the slide background --> + +<div class="background"> + + <div class="header"> + <!-- sized and colored via CSS --> + </div> + + <div class="footer"></div> + </div> + +<div class="slide titlepage"> +<div style="height: 135px; width: 480px; overflow: hidden; position: fixed; top: auto; bottom: 10px; left: auto; right: 0; "> +<img src="../gordon/bumper480x270.png" style="margin: -135px 0 0 0;"/> +</div> +<!-- <img src="../google.png" style="position: fixed; top: auto; bottom: 30px; left: 20px; right: auto;"/> --> +<br/> +<img src="../go-logo-white.png"> +<br/> +<br/> +<h1 style="padding-right: 0pt; margin-right: 0pt; color: #0066cc; font-size: 250%; border-bottom: 0px;">The Go Programming Language</h1> +<div style="color: #ffcc00;"> +<h2>Russ Cox</h2> +<!-- <h3><i>rsc@google.com</i></h3> --> +<br/> +<h3>CNS Winter Research Review<br/><br/>January 21, 2010</h3> +<br/> +<br/> +<!-- +<h4><i>click to start; then left/right arrow to change slides</i></h4> --> +</div> +</div> + +<div class="slide"> + <h1>Go</h1> + + <h2>New</h2> + <h2>Experimental</h2> + <h2>Concurrent</h2> + <h2>Garbage-collected</h2> + <h2>Systems</h2> + <h2>Language</h2> +</div> + +<div class="slide"> + <h1>Hello, world</h1> +<pre> +package main + +import "fmt" + +func main() { + fmt.Printf("Hello, 世界\n") +} +</pre> +</div> + +<div class="slide"> + <h1>History</h1> + + <h2>Design started in late 2007.</h2> + <h2>Implementation starting to work mid-2008.</h2> + <h2>Released as an open source project in November 2009.</h2> + <h2>Work continues.<h2> + <h2>Robert Griesemer, Ken Thompson, Rob Pike, Ian Lance Taylor, Russ Cox, many others</h2> +</div> + +<div class="slide"> + <h1>Goals and Motivation</h1> + + <h2>Go fast!</h2> + <h2>Make programming fun again.</h2> + <h2>Targeted at systems software, broadly.</h2> +</div> + +<div class="slide"> + <h1>Why isn't programming fun?</h1> + + <div class="incremental"> + <h2>Compiled, statically-typed languages (C, C++, Java) require too much typing and too much typing:</h2> + + <ul> + <li>verbose, lots of repetition</li> + <li>too much focus on type hierarchy</li> + <li>types get in the way as much as they help</li> + <li>compiles take far too long</li> + </ul> + </div> + + <div class="incremental"> + <h2>Dynamic languages (Python, JavaScript) fix these problems (no more types, no more compiler) but introduce others:</h2> + + <ul> + <li>errors at run time that should be caught statically</li> + <li>no compilation means slow code</li> + </ul> + </div> + + <h2 class="incremental">Can we combine the best of both?</h2> +</div> + +<div class="slide"> + <h1>Why a new language?</h1> + + <div class="incremental"> + <h2>No new systems language in 10+ years.</h2> + <h2>Current languages designed before ...</h2> + <h3>... rise of large-scale, networked and multicore computing</h3> + <h3>... rise of Internet-scale distributed development (many libraries)</h3> + </div> +</div> + +<div class="slide"> + <h1>Go</h1> + + <h2>Make the language fast.</h2> + <h2>Make the tools fast.</h2> +</div> + +<div class="slide"> + <h1>Compilation Demo</h1> + + <h2>Build all standard Go packages: ~120,000 lines of code.</h2> +</div> + +<div class="slide"> + <h1>Go in one slide</h1> + + <h2 class="incremental">Lightweight syntax.</h2> + + <h2 class="incremental">Static types: enough to compile well, but inferred much of the time.</h2> + + <h2 class="incremental">Methods: on any type, orthogonal to type system.</h2> + + <h2 class="incremental">Abstract types: interface values, relations inferred statically.</h2> + + <h2 class="incremental">Visibility: inferred from case of name.</h2> + + <h2 class="incremental">First-class functions.</h2> + + <h2 class="incremental">Garbage collection.</h2> + + <br/> + + <h2 class="incremental">Lightweight feel of a scripting language but compiled.</h2> +</div> + +<div class="slide"> + <h1>Go, concurrently</h1> + + <h2>Cheap to create a new flow of control (goroutine):</h2> + +<pre> +func main() { + go expensiveComputation(x, y, z) + anotherExpensiveComputation(a, b, c) +} +</pre> + + <h2>Two expensive computations in parallel.</h2> +</div> + +<div class="slide"> + <h1>Go, concurrently</h1> + + <h2>Cheap to create a new flow of control (goroutine):</h2> + +<pre> + for { + rw := l.Accept() + conn := newConn(rw, handler) + go conn.serve() + } +</pre> + + <h2>Concurrent web server.</h2> + <h2>Network connections multiplexed onto epoll.</h2> + <ul> + <li>many blocked Read calls != many blocked OS threads</li> + </ul> + +</div> + +<div class="slide"> + <h1>Go, synchronized</h1> + + <h2>Use explicit messages to communicate and synchronize.</h2> + +<pre> +func computeAndSend(ch chan int, x, y, z int) { + ch <- expensiveComputation(x, y, z) +} + +func main() { + ch := make(chan int) + go computeAndSend(ch, x, y, z) + v2 := anotherExpensiveComputation(a, b, c) + v1 := <-ch + fmt.Println(v1, v2) +} +</pre> + <h2>Notice communication of result in addition to synchronization.</h2> +</div> + +<div class="slide"> + <h1>Go, synchronized</h1> + + <h2>RPC client</h2> + +<pre> +func (client *Client) Call(method string, args, reply interface{}) os.Error { + // Send RPC message. + call := client.Go(method, args, reply, nil) + + // Read reply from Done channel. + <-call.Done + + return call.Error +} +</pre> +</div> + +<div class="slide"> + <h1>Go, synchronized</h1> + + <h2>RPC client demux</h2> + +<pre> +func (client *Client) input() { + for { + resp := client.readResponse() + client.mutex.Lock() + c := client.pending[resp.Seq] + client.pending[resp.Seq] = c, false + client.mutex.Unlock() + if resp.Error != "" { + c.Error = os.ErrorString(resp.error) + } + resp.Decode(c.Reply) + c.Done <- c + } +} +</pre> +</div> + +<div class="slide"> + <h1>Go, synchronized</h1> + + <h2>RPC client demux</h2> + +<pre> +func (client *Client) input() { + for { + <font style="color: black;">resp := client.readResponse()</font> + client.mutex.Lock() + c := client.pending[resp.Seq] + client.pending[resp.Seq] = c, false + client.mutex.Unlock() + if resp.Error != "" { + c.Error = os.ErrorString(resp.error) + } + resp.Decode(c.Reply) + c.Done <- c + } +} +</pre> +<h2>Read response from network.</h2 +</div> + +<div class="slide"> + <h1>Go, synchronized</h1> + + <h2>RPC client demux</h2> + +<pre> +func (client *Client) input() { + for { + resp := client.readResponse() + <font style="color: black;">client.mutex.Lock() + c := client.pending[resp.Seq] + client.pending[resp.Seq] = c, false + client.mutex.Unlock()</font> + if resp.Error != "" { + c.Error = os.ErrorString(resp.error) + } + resp.Decode(c.Reply) + c.Done <- c + } +} +</pre> +<h2>Look up request by sequence number.</h2 +</div> + +<div class="slide"> + <h1>Go, synchronized</h1> + + <h2>RPC client demux</h2> + +<pre> +func (client *Client) input() { + for { + resp := client.readResponse() + client.mutex.Lock() + c := client.pending[resp.Seq] + client.pending[resp.Seq] = c, false + client.mutex.Unlock() + <font style="color: black;">if resp.Error != "" { + c.Error = os.ErrorString(resp.error) + } + resp.Decode(c.Reply)</font> + c.Done <- c + } +} +</pre> +<h2>Decode response fields from payload.</h2 +</div> + +<div class="slide"> + <h1>Go, synchronized</h1> + + <h2>RPC client demux</h2> + +<pre> +func (client *Client) input() { + for { + resp := client.readResponse() + client.mutex.Lock() + c := client.pending[resp.Seq] + client.pending[resp.Seq] = c, false + client.mutex.Unlock() + if resp.Error != "" { + c.Error = os.ErrorString(resp.error) + } + resp.Decode(c.Reply) + <font style="color: black;">c.Done <- c</font> + } +} +</pre> +<h2>Tell client that it finished.</h2 +</div> + +<div class="slide"> + <h1>Go, synchronized</h1> + + <h2>RPC client demux</h2> + +<pre> +func (client *Client) input() { + for { + resp := client.readResponse() + client.mutex.Lock() + c := client.pending[resp.Seq] + client.pending[resp.Seq] = c, false + client.mutex.Unlock() + if resp.Error != "" { + c.Error = os.ErrorString(resp.error) + } + resp.Decode(c.Reply) + c.Done <- c + } +} +</pre> + +<h2>Can create multiple Calls with same Done channel +and distinguish which finished by inspecting value sent on channel. +</h2> + +</div> + +<div class="slide"> + <h1>Goroutine demo</h1> + + <h2>Chain together 100,000 goroutines connected by 100,001 channels.</h2> + + <h2>Send a value to one end of the chain.</h2> + + <h2>Each passes it along, increments.</h2> + + <h2>Receive value out the other end of the chain.</h2> +</div> + + +<div class="slide"> + <h1>Go Status</h1> +</div> + +<div class="slide"> + <h1>Go Status</h1> + + <h2>Open source:</h2> + <ul> + <li>released on November 10, 2009 + <li>regular releases (~ weekly) + <li>all development done in public Mercurial repository + <li>outside contributions welcome + <li>two independent compiler implementations + <li>XML, JSON, HTTP, TLS/SSL, native RPC, (network channels,) ... + </ul> +</div> + +<div class="slide"> + <h1>Go Status</h1> + + <h2>Open source</h2> + + <h2>Portable:</h2> + <ul> + <li>FreeBSD, Linux, OS X (x86, x86-64) + <li>(in progress) Linux arm, Native Client x86, Windows x86. + </ul> +</div> + +<div class="slide"> + <h1>Go Status</h1> + + <h2>Open source</h2> + <h2>Portable</h2> + + <h2>Still in progress, experimental. Yet to come:</h2> + <ul> + <li>production garbage collector + <li>generics? + <li>exceptions? + <li>unions or sum types? + </ul> +</div> + +<div class="slide titlepage"> + <h1>Questions?</h1> + <br><br> + <center> + <img src="../gordon/bumper640x360.png"> + </center> + <br><br> + <div style="color: #ffcc00;"> + <!-- <h3><i>rsc@google.com</i></h3> --> + </div> +</div> + +</body></html> diff --git a/doc/talks/go_talk-20100323.html b/doc/talks/go_talk-20100323.html new file mode 100644 index 000000000..3143b079a --- /dev/null +++ b/doc/talks/go_talk-20100323.html @@ -0,0 +1,395 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> +<title>Go Tech Talk</title> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> +<meta name="font-size-adjustment" content="-1" /> +<link rel="stylesheet" href="slidy.css" + type="text/css" media="screen, projection, print" /> +<script src="slidy.js" type="text/javascript"> +</script> +</head> +<body> +<!-- this defines the slide background --> + +<div class="background"> + + <div class="header"> + <!-- sized and colored via CSS --> + </div> + + <div class="footer"></div> + </div> + +<div class="slide titlepage"> +<br/> +<br/> +<img src="../go-logo-white.png" width="588px" height="217px"> +<br/> +<h1 style="padding-right: 0pt; margin-right: 0pt; color: #0066cc; font-size: 250%; border-bottom: 0px;">The Go Programming Language</h1> +<div style="color: #ffcc00;"> +<br/> +<h3>Sydney University<br/><br/>March 23, 2010</h3> +</div> +</div> + +<div class="slide"> + <h1>Go</h1> + + <h2>New</h2> + <h2>Experimental</h2> + <h2>Concurrent</h2> + <h2>Garbage Collected</h2> + <h2>Systems Language</h2> +</div> + +<div class="slide"> + <h1>Hello, world</h1> +<pre> +package main + +import "fmt" + +func main() { + fmt.Printf("Hello, 世界\n") +} +</pre> +</div> + +<div class="slide"> + <h1>Hello, world 2.0</h1> + + <h2>Serving <a href="http://localhost:8080/world">http://localhost:8080/world</a></h2> +<pre> +package main + +import ( + "fmt" + "http" +) + +func handler(c *http.Conn, r *http.Request) { + fmt.Fprintf(c, "Hello, %s.", r.URL.Path[1:]) +} + +func main() { + http.ListenAndServe(":8080", + http.HandlerFunc(handler)) +} +</pre> +</div> + +<div class="slide"> + <h1>New</h1> + + <h2>It's about two years old:</h2> + <ul> + <li>Design started in late 2007</li> + <li>Implementation starting to work mid-2008</li> + <li>Released as an open source project in November 2009</li> + <li>Development continues with an active community</li> + </ul> + + <h2>Why invent a new language? Older languages weren't designed for concurrency, but modern software needs it:</h2> + <ul> + <li>Large scale, networked computing, such as Google web search</li> + <li>Multi-core hardware</li> + </ul> +</div> + +<div class="slide"> + <h1>New</h1> + + <h2>Older languages are also frustrating on a day-to-day basis</h2> + <h2>Statically-typed languages (C, C++, Java) have issues:</h2> + <ul> + <li>Edit-Compile-Run cycle takes far too long</li> + <li>Type hierarchy can hurt as much as it helps</li> + </ul> +<div style="text-align:center"> +<img src="java-typing.png" width="800px" height="90px"><br> +</div> + + <h2>Dynamic languages (Python, JavaScript) fix some issues but introduce others:</h2> + <ul> + <li>No compilation means slow code</li> + <li>Runtime errors that should be caught statically</li> + </ul> + + <h2>Go has the lighter feel of a scripting language but is compiled</h2> +</div> + +<div class="slide"> + <h1>New</h1> + + <h2>Large C++ programs (e.g. Firefox, OpenOffice, Chromium) have enormous build times:</h2> + <ul> + <li>XKCD's #1 Programmer Excuse for Legitimately Slacking Off: "<a href="http://xkcd.com/303/">My Code's Compiling</a>"</li> + </ul> + + <h2>On a Mac (OS X 10.5.8, gcc 4.0.1):</h2> + <ul> + <li>C: <code>#include <stdio.h></code> reads 360 lines from 9 files</li> + <li>C++: <code>#include <iostream></code> reads 25,326 lines from 131 files</li> + <li>Objective-C: <code>#include <Carbon/Carbon.h></code> reads 124,730 lines from 689 files</li> + <li>We haven't done any real work yet!</li> + </ul> + + <h2>In Go: <code>import "fmt"</code> reads <i>one</i> file: 184 lines summarizing 7 packages</h2> +</div> + +<div class="slide"> + <h1>New</h1> + + <h2>Compilation demo</h2> +</div> + +<div class="slide"> + <h1>Experimental</h1> + + <h2>Go is still unproven</h2> + <h2>Language is still evolving</h2> + <h2>Package library is incomplete</h2> + <h2>Concurrent garbage collection is an active research problem</h2> + <h2>Reviving forgotten concepts:</h2> + <ul> + <li>Go's concurrency is strongly influenced by <i>Communicating Sequential Processes</i> (Hoare, 1978)</li> + <li>Go has types and interfaces, but no inheritance. It is arguably more object-oriented than previously mentioned languages, being closer to the original Smalltalk meaning (1970s)</li> + </ul> +</div> + +<div class="slide"> + <h1>Concurrent</h1> + + <h2>Unix philosophy: write <i>programs</i> that do one thing and do it well</h2> + <h2>Connect them with <i>pipes</i>:</h2> + <ul> + <li>How many lines of test code are there in the Go standard library?</li> + <li><code>find ~/go/src/pkg | grep _test.go$ | xargs wc -l</code></li> + </ul> + + <h2>Unlike other languages, Go makes it easy to:</h2> + <ul> + <li>Launch <i>goroutines</i></li> + <li>Connect them with <i>channels</i></li> + </ul> +</div> + +<div class="slide"> + <h1>Concurrent</h1> + + <h2>Start a new flow of control with the <code>go</code> keyword</h2> + <h2>Parallel computation is easy:</h2> +<pre> +func main() { + go expensiveComputation(x, y, z) + anotherExpensiveComputation(a, b, c) +} +</pre> + + <h2>Roughly speaking, a goroutine is like a thread, but lighter weight:</h2> + <ul> + <li>Goroutines have segmented stacks, and typically smaller stacks</li> + <li>This requires compiler support. Goroutines can't just be a C++ library on top of a thread library</li> + </ul> +</div> + +<div class="slide"> + <h1>Concurrent</h1> + + <h2>Consider web servers ("the C10k problem"):</h2> + <ul> + <li>"Thread per connection" approach is conceptually neat, but doesn't scale well in practice</li> + <li>What does scale well (event-driven callbacks, asynchronous APIs) are harder to understand, maintain, and debug</li> + <li>We think "goroutine per connection" can scale well, and is conceptually neat</li> + </ul> +<pre> + for { + rw := socket.Accept() + conn := newConn(rw, handler) + go conn.serve() + } +</pre> +</div> + +<div class="slide"> + <h1>Concurrent</h1> + + <h2>Let's look again at our simple parallel computation:</h2> +<pre> +func main() { + go expensiveComputation(x, y, z) + anotherExpensiveComputation(a, b, c) +} +</pre> + + <h2>This story is incomplete:</h2> + <ul> + <li>How do we know when the two computations are done?</li> + <li>What are their values?</li> + </ul> +</div> + +<div class="slide"> + <h1>Concurrent</h1> + + <h2>Goroutines communicate with other goroutines via channels</h2> +<pre> +func computeAndSend(ch chan int, x, y, z int) { + ch <- expensiveComputation(x, y, z) +} + +func main() { + ch := make(chan int) + go computeAndSend(ch, x, y, z) + v2 := anotherExpensiveComputation(a, b, c) + v1 := <-ch + fmt.Println(v1, v2) +} +</pre> + +</div> + +<div class="slide"> + <h1>Concurrent</h1> + + <h2>In traditional concurrent programs, you <i>communicate by sharing memory</i>. In Go, you <i>share memory by communicating</i>:</h2> + <ul> + <li>Communication (the <code><-</code> operator) is sharing and synchronization</li> + </ul> + + <h2>Threads and locks are concurrency primitives; CSP is a concurrency model:</h2> + <ul> + <li>Analogy: "Go To Statement Considered Harmful" (Dijsktra, 1968)</li> + <li><code>goto</code> is a control flow primitive; structured programming (<code>if</code> statements, <code>for</code> loops, function calls) is a control flow model</li> + </ul> + + <h2>Learning CSP changes the way you think about concurrent programming:</h2> + <ul> + <li>Every language has its grain. If your Go program uses mutexes, you're probably working against the grain</li> + </ul> +</div> + +<div class="slide"> + <h1>Garbage Collected</h1> + + <h2>Automatic memory management makes writing (and maintaining) programs easier</h2> + <h2>Especially in a concurrent world:</h2> + <ul> + <li>Who "owns" a shared piece of memory, and is responsible for destroying it?</li> + </ul> + + <h2>Large C++ programs usually end up with semi-automatic memory management anyway, via "smart pointers"</h2> + <h2>Mixing the two models can be problematic:</h2> + <ul> + <li>Browsers can leak memory easily; DOM elements are C++ objects, but JavaScript is garbage collected</li> + </ul> +</div> + +<div class="slide"> + <h1>Garbage Collected</h1> + + <h2>Go is also a safer language:</h2> + <ul> + <li>Pointers but no pointer arithmetic</li> + <li>No dangling pointers</li> + <li>Variables are zero-initialized</li> + <li>Array access is bounds-checked</li> + </ul> + + <h2>No buffer overflow exploits</h2> +</div> + +<div class="slide"> + <h1>Systems Language</h1> + + <h2>This just means you could write decently large programs in Go:</h2> + <ul> + <li>Web servers</li> + <li>Web browsers</li> + <li>Web crawlers</li> + <li>Search indexers</li> + <li>Databases</li> + <li>Word processors</li> + <li>Integrated Development Environments (IDEs)</li> + <li>Operating systems</li> + <li>...</li> + </ul> +</div> + +<div class="slide"> + <h1>Systems Language</h1> + + <h2>Garbage collection has a reputation for being "slower"</h2> + <h2>We're expecting Go to be slightly slower than optimized C, but faster than Java, depending on the task. Nonetheless:</h2> + <ul> + <li>Fast and buggy is worse than almost-as-fast and correct</li> + <li>It is easier to optimize a correct program than to correct an optimized program</li> + <li>Fundamentally, it's simply a trade-off we're willing to make</li> + </ul> + + <h2>Memory layout can drastically affect performance. These two designs are equivalent in Go, but significantly different in Java:</h2> +<pre> +type Point struct { X, Y int } +type Rect struct { P0, P1 Point } + +// or ... + +type Rect struct { X0, Y0, X1, Y1 int } +</pre> +</div> + +<div class="slide"> + <h1>Systems Language</h1> + + <h2>Quote from http://loadcode.blogspot.com/2009/12/go-vs-java.html</h2> + +<h2> +"[Git] is known to be very fast. It is written in C. A Java version +JGit was made. It was considerably slower. Handling of memory and lack +of unsigned types was some of the important reasons. +</h2> + +<h2>Shawn O. Pearce wrote on the git mailinglist:</h2> +<ul><li>"JGit struggles with not +having an efficient way to represent a SHA-1. C can just say "unsigned +char[20]" and have it inline into the container's memory allocation. A +byte[20] in Java will cost an *additional* 16 bytes of memory, and be +slower to access because the bytes themselves are in a different area +of memory from the container object. We try to work around it by +converting from a byte[20] to 5 ints, but that costs us machine +instructions" +</li></ul> + +<h2> +Like C, Go does allow unsigned types and defining data structures +containing other data structures as continuous blocks of memory." +</h2> +</div> + +<div class="slide"> + <h1>Go</h1> + + <h2>New</h2> + <h2>Experimental</h2> + <h2>Concurrent</h2> + <h2>Garbage Collected</h2> + <h2>Systems Language</h2> + + <h2>And more:</h2> + <ul> + <li>I haven't talked about the type system, interfaces, slices, closures, selects, ...</li> + <li>Tutorial, documentation, mailing list, source code all online</li> + </ul> +</div> + +<div class="slide titlepage"> + <h1>Questions?</h1> + <br><br> + <center> + <img src="../gordon/bumper640x360.png" width="640px" height="360px"> + </center> +</div> + +</body></html> diff --git a/doc/talks/gofrontend-gcc-summit-2010.pdf b/doc/talks/gofrontend-gcc-summit-2010.pdf Binary files differnew file mode 100644 index 000000000..157fd7676 --- /dev/null +++ b/doc/talks/gofrontend-gcc-summit-2010.pdf diff --git a/doc/talks/io2010/balance.go b/doc/talks/io2010/balance.go new file mode 100644 index 000000000..b01f7468c --- /dev/null +++ b/doc/talks/io2010/balance.go @@ -0,0 +1,168 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "container/heap" + "flag" + "fmt" + "rand" + "time" +) + +const nRequester = 100 +const nWorker = 10 + +var roundRobin = flag.Bool("r", false, "use round-robin scheduling") + +// Simulation of some work: just sleep for a while and report how long. +func op() int { + n := rand.Int63n(1e9) + time.Sleep(nWorker * n) + return int(n) +} + +type Request struct { + fn func() int + c chan int +} + +func requester(work chan Request) { + c := make(chan int) + for { + time.Sleep(rand.Int63n(nWorker * 2e9)) + work <- Request{op, c} + <-c + } +} + +type Worker struct { + i int + requests chan Request + pending int +} + +func (w *Worker) work(done chan *Worker) { + for { + req := <-w.requests + req.c <- req.fn() + done <- w + } +} + +type Pool []*Worker + +func (p Pool) Len() int { return len(p) } + +func (p Pool) Less(i, j int) bool { + return p[i].pending < p[j].pending +} + +func (p *Pool) Swap(i, j int) { + a := *p + a[i], a[j] = a[j], a[i] + a[i].i = i + a[j].i = j +} + +func (p *Pool) Push(x interface{}) { + a := *p + n := len(a) + a = a[0 : n+1] + w := x.(*Worker) + a[n] = w + w.i = n + *p = a +} + +func (p *Pool) Pop() interface{} { + a := *p + *p = a[0 : len(a)-1] + w := a[len(a)-1] + w.i = -1 // for safety + return w +} + +type Balancer struct { + pool Pool + done chan *Worker + i int +} + +func NewBalancer() *Balancer { + done := make(chan *Worker, nWorker) + b := &Balancer{make(Pool, 0, nWorker), done, 0} + for i := 0; i < nWorker; i++ { + w := &Worker{requests: make(chan Request, nRequester)} + heap.Push(&b.pool, w) + go w.work(b.done) + } + return b +} + +func (b *Balancer) balance(work chan Request) { + for { + select { + case req := <-work: + b.dispatch(req) + case w := <-b.done: + b.completed(w) + } + b.print() + } +} + +func (b *Balancer) print() { + sum := 0 + sumsq := 0 + for _, w := range b.pool { + fmt.Printf("%d ", w.pending) + sum += w.pending + sumsq += w.pending * w.pending + } + avg := float64(sum) / float64(len(b.pool)) + variance := float64(sumsq)/float64(len(b.pool)) - avg*avg + fmt.Printf(" %.2f %.2f\n", avg, variance) +} + +func (b *Balancer) dispatch(req Request) { + if *roundRobin { + w := b.pool[b.i] + w.requests <- req + w.pending++ + b.i++ + if b.i >= len(b.pool) { + b.i = 0 + } + return + } + + w := heap.Pop(&b.pool).(*Worker) + w.requests <- req + w.pending++ + // fmt.Printf("started %p; now %d\n", w, w.pending) + heap.Push(&b.pool, w) +} + +func (b *Balancer) completed(w *Worker) { + if *roundRobin { + w.pending-- + return + } + + w.pending-- + // fmt.Printf("finished %p; now %d\n", w, w.pending) + heap.Remove(&b.pool, w.i) + heap.Push(&b.pool, w) +} + +func main() { + flag.Parse() + work := make(chan Request) + for i := 0; i < nRequester; i++ { + go requester(work) + } + NewBalancer().balance(work) +} diff --git a/doc/talks/io2010/decrypt.go b/doc/talks/io2010/decrypt.go new file mode 100644 index 000000000..0a6c006e2 --- /dev/null +++ b/doc/talks/io2010/decrypt.go @@ -0,0 +1,85 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This code differs from the slides in that it handles errors. + +package main + +import ( + "crypto/aes" + "crypto/cipher" + "compress/gzip" + "io" + "log" + "os" +) + +func EncryptAndGzip(dstfile, srcfile string, key, iv []byte) os.Error { + r, err := os.Open(srcfile) + if err != nil { + return err + } + var w io.Writer + w, err = os.Create(dstfile) + if err != nil { + return err + } + c, err := aes.NewCipher(key) + if err != nil { + return err + } + w = cipher.StreamWriter{S: cipher.NewOFB(c, iv), W: w} + w2, err := gzip.NewWriter(w) + if err != nil { + return err + } + defer w2.Close() + _, err = io.Copy(w2, r) + return err +} + +func DecryptAndGunzip(dstfile, srcfile string, key, iv []byte) os.Error { + f, err := os.Open(srcfile) + if err != nil { + return err + } + defer f.Close() + c, err := aes.NewCipher(key) + if err != nil { + return err + } + r := cipher.StreamReader{S: cipher.NewOFB(c, iv), R: f} + r2, err := gzip.NewReader(r) + if err != nil { + return err + } + w, err := os.Create(dstfile) + if err != nil { + return err + } + defer w.Close() + _, err = io.Copy(w, r2) + return err +} + +func main() { + err := EncryptAndGzip( + "/tmp/passwd.gz", + "/etc/passwd", + make([]byte, 16), + make([]byte, 16), + ) + if err != nil { + log.Fatal(err) + } + err = DecryptAndGunzip( + "/dev/stdout", + "/tmp/passwd.gz", + make([]byte, 16), + make([]byte, 16), + ) + if err != nil { + log.Fatal(err) + } +} diff --git a/doc/talks/io2010/encrypt.go b/doc/talks/io2010/encrypt.go new file mode 100644 index 000000000..c6508bba1 --- /dev/null +++ b/doc/talks/io2010/encrypt.go @@ -0,0 +1,52 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This code differs from the slides in that it handles errors. + +package main + +import ( + "crypto/aes" + "crypto/cipher" + "compress/gzip" + "io" + "log" + "os" +) + +func EncryptAndGzip(dstfile, srcfile string, key, iv []byte) os.Error { + r, err := os.Open(srcfile) + if err != nil { + return err + } + var w io.WriteCloser + w, err = os.Create(dstfile) + if err != nil { + return err + } + defer w.Close() + w, err = gzip.NewWriter(w) + if err != nil { + return err + } + defer w.Close() + c, err := aes.NewCipher(key) + if err != nil { + return err + } + _, err = io.Copy(cipher.StreamWriter{S: cipher.NewOFB(c, iv), W: w}, r) + return err +} + +func main() { + err := EncryptAndGzip( + "/tmp/passwd.gz", + "/etc/passwd", + make([]byte, 16), + make([]byte, 16), + ) + if err != nil { + log.Fatal(err) + } +} diff --git a/doc/talks/io2010/eval1.go b/doc/talks/io2010/eval1.go new file mode 100644 index 000000000..2d7fc3be6 --- /dev/null +++ b/doc/talks/io2010/eval1.go @@ -0,0 +1,229 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "bufio" + "fmt" + "os" + "strconv" + "strings" +) + +// Generic expression parser/evaluator + +type Value interface { + String() string + BinaryOp(op string, y Value) Value +} + +type Parser struct { + precTab map[string]int + newVal func(string) Value + src string + pos int + tok string +} + +const alphanum = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + +func (p *Parser) stop(c uint8) bool { + switch { + case p.pos >= len(p.src): + return true + case c == '"': + if p.src[p.pos] == '"' { + p.pos++ + return true + } + return false + case strings.IndexRune(alphanum, int(c)) >= 0: + return strings.IndexRune(alphanum, int(p.src[p.pos])) < 0 + } + return true +} + +func (p *Parser) next() { + // skip blanks + for ; p.pos < len(p.src) && p.src[p.pos] <= ' '; p.pos++ { + } + if p.pos >= len(p.src) { + p.tok = "" + return + } + start := p.pos + c := p.src[p.pos] + for p.pos < len(p.src) { + p.pos++ + if p.stop(c) { + break + } + } + p.tok = p.src[start:p.pos] +} + +func (p *Parser) binaryExpr(prec1 int) Value { + x := p.newVal(p.tok) + p.next() + for prec := p.precTab[p.tok]; prec >= prec1; prec-- { + for p.precTab[p.tok] == prec { + op := p.tok + p.next() + y := p.binaryExpr(prec + 1) + x = x.BinaryOp(op, y) + } + } + return x +} + +func Eval(precTab map[string]int, newVal func(string) Value, src string) Value { + var p Parser + p.precTab = precTab + p.newVal = newVal + p.src = src + p.next() + return p.binaryExpr(1) +} + +// Command-line expression evaluator + +func main() { + r := bufio.NewReader(os.Stdin) + for { + fmt.Printf("> ") + line, err := r.ReadString('\n') + if err != nil { + break + } + fmt.Printf("%s\n", Eval(precTab, trace(newVal), line)) + } +} + + +// Custom grammar and values + +var precTab = map[string]int{ + "&&": 1, + "||": 2, + "==": 3, + "!=": 3, + "<": 3, + "<=": 3, + ">": 3, + ">=": 3, + "+": 4, + "-": 4, + "*": 5, + "/": 5, + "%": 5, +} + +func newVal(lit string) Value { + x, err := strconv.Atoi(lit) + if err == nil { + return Int(x) + } + b, err := strconv.Atob(lit) + if err == nil { + return Bool(b) + } + return Error(fmt.Sprintf("illegal literal '%s'", lit)) +} + +type Error string + +func (e Error) String() string { return string(e) } +func (e Error) BinaryOp(op string, y Value) Value { return e } + +type Int int + +func (x Int) String() string { return strconv.Itoa(int(x)) } +func (x Int) BinaryOp(op string, y Value) Value { + switch y := y.(type) { + case Error: + return y + case Int: + switch op { + case "+": + return x + y + case "-": + return x - y + case "*": + return x * y + case "/": + return x / y + case "%": + return x % y + case "==": + return Bool(x == y) + case "!=": + return Bool(x != y) + case "<": + return Bool(x < y) + case "<=": + return Bool(x <= y) + case ">": + return Bool(x > y) + case ">=": + return Bool(x >= y) + } + } + return Error(fmt.Sprintf("illegal operation: '%v %s %v'", x, op, y)) +} + +type Bool bool + +func (x Bool) String() string { return strconv.Btoa(bool(x)) } +func (x Bool) BinaryOp(op string, y Value) Value { + switch y := y.(type) { + case Error: + return y + case Bool: + switch op { + case "&&": + return Bool(x && y) + case "||": + return Bool(x || y) + case "==": + return Bool(x == y) + case "!=": + return Bool(x != y) + } + } + return Error(fmt.Sprintf("illegal operation: '%v %s %v'", x, op, y)) +} + + +func trace(newVal func(string) Value) func(string) Value { + return func(s string) Value { + v := newVal(s) + fmt.Printf("\tnewVal(%q) = %s\n", s, fmtv(v)) + return &traceValue{v} + } +} + +type traceValue struct { + Value +} + +func (x *traceValue) BinaryOp(op string, y Value) Value { + z := x.Value.BinaryOp(op, y.(*traceValue).Value) + fmt.Printf("\t%s.BinaryOp(%q, %s) = %s\n", fmtv(x.Value), op, fmtv(y.(*traceValue).Value), fmtv(z)) + return &traceValue{z} +} + +func (x *traceValue) String() string { + s := x.Value.String() + fmt.Printf("\t%s.String() = %#v\n", fmtv(x.Value), s) + return s +} + +func fmtv(v Value) string { + t := fmt.Sprintf("%T", v) + if i := strings.LastIndex(t, "."); i >= 0 { // strip package + t = t[i+1:] + } + return fmt.Sprintf("%s(%#v)", t, v) +} diff --git a/doc/talks/io2010/eval2.go b/doc/talks/io2010/eval2.go new file mode 100644 index 000000000..5524c8b3a --- /dev/null +++ b/doc/talks/io2010/eval2.go @@ -0,0 +1,261 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "bufio" + "fmt" + "os" + "strconv" + "strings" +) + +// Generic expression parser/evaluator + +type Value interface { + String() string + BinaryOp(op string, y Value) Value +} + +type Parser struct { + precTab map[string]int + newVal func(string) Value + src string + pos int + tok string +} + +const alphanum = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + +func (p *Parser) stop(c uint8) bool { + switch { + case p.pos >= len(p.src): + return true + case c == '"': + if p.src[p.pos] == '"' { + p.pos++ + return true + } + return false + case strings.IndexRune(alphanum, int(c)) >= 0: + return strings.IndexRune(alphanum, int(p.src[p.pos])) < 0 + } + return true +} + +func (p *Parser) next() { + // skip blanks + for ; p.pos < len(p.src) && p.src[p.pos] <= ' '; p.pos++ { + } + if p.pos >= len(p.src) { + p.tok = "" + return + } + start := p.pos + c := p.src[p.pos] + for p.pos < len(p.src) { + p.pos++ + if p.stop(c) { + break + } + } + p.tok = p.src[start:p.pos] +} + +func (p *Parser) binaryExpr(prec1 int) Value { + x := p.newVal(p.tok) + p.next() + for prec := p.precTab[p.tok]; prec >= prec1; prec-- { + for p.precTab[p.tok] == prec { + op := p.tok + p.next() + y := p.binaryExpr(prec + 1) + x = x.BinaryOp(op, y) + } + } + return x +} + +func Eval(precTab map[string]int, newVal func(string) Value, src string) Value { + var p Parser + p.precTab = precTab + p.newVal = newVal + p.src = src + p.next() + return p.binaryExpr(1) +} + +// Command-line expression evaluator + +func main() { + r := bufio.NewReader(os.Stdin) + for { + fmt.Printf("> ") + line, err := r.ReadString('\n') + if err != nil { + break + } + fmt.Printf("%s\n", Eval(precTab, trace(newVal), line)) + } +} + + +// Custom grammar and values + +var precTab = map[string]int{ + "&&": 1, + "||": 2, + "==": 3, + "!=": 3, + "<": 3, + "<=": 3, + ">": 3, + ">=": 3, + "+": 4, + "-": 4, + "*": 5, + "/": 5, + "%": 5, +} + +func newVal(lit string) Value { + x, err := strconv.Atoi(lit) + if err == nil { + return Int(x) + } + b, err := strconv.Atob(lit) + if err == nil { + return Bool(b) + } + s, err := strconv.Unquote(lit) + if err == nil { + return String(s) + } + return Error(fmt.Sprintf("illegal literal '%s'", lit)) +} + +type Error string + +func (e Error) String() string { return string(e) } +func (e Error) BinaryOp(op string, y Value) Value { return e } + +type Int int + +func (x Int) String() string { return strconv.Itoa(int(x)) } +func (x Int) BinaryOp(op string, y Value) Value { + switch y := y.(type) { + case Error: + return y + case String: + switch op { + case "*": + return String(strings.Repeat(string(y), int(x))) + } + case Int: + switch op { + case "+": + return x + y + case "-": + return x - y + case "*": + return x * y + case "/": + return x / y + case "%": + return x % y + case "==": + return Bool(x == y) + case "!=": + return Bool(x != y) + case "<": + return Bool(x < y) + case "<=": + return Bool(x <= y) + case ">": + return Bool(x > y) + case ">=": + return Bool(x >= y) + } + } + return Error(fmt.Sprintf("illegal operation: '%v %s %v'", x, op, y)) +} + +type Bool bool + +func (x Bool) String() string { return strconv.Btoa(bool(x)) } +func (x Bool) BinaryOp(op string, y Value) Value { + switch y := y.(type) { + case Error: + return y + case Bool: + switch op { + case "&&": + return Bool(x && y) + case "||": + return Bool(x || y) + case "==": + return Bool(x == y) + case "!=": + return Bool(x != y) + } + } + return Error(fmt.Sprintf("illegal operation: '%v %s %v'", x, op, y)) +} + +type String string + +func (x String) String() string { return strconv.Quote(string(x)) } +func (x String) BinaryOp(op string, y Value) Value { + switch y := y.(type) { + case Error: + return y + case Int: + switch op { + case "*": + return String(strings.Repeat(string(x), int(y))) + } + case String: + switch op { + case "+": + return x + y + case "<": + return Bool(x < y) + } + } + return Error(fmt.Sprintf("illegal operation: '%v %s %v'", x, op, y)) +} + + +func trace(newVal func(string) Value) func(string) Value { + return func(s string) Value { + v := newVal(s) + fmt.Printf("\tnewVal(%q) = %s\n", s, fmtv(v)) + return &traceValue{v} + } +} + +type traceValue struct { + Value +} + +func (x *traceValue) BinaryOp(op string, y Value) Value { + z := x.Value.BinaryOp(op, y.(*traceValue).Value) + fmt.Printf("\t%s.BinaryOp(%q, %s) = %s\n", fmtv(x.Value), op, fmtv(y.(*traceValue).Value), fmtv(z)) + return &traceValue{z} +} + +func (x *traceValue) String() string { + s := x.Value.String() + fmt.Printf("\t%s.String() = %#v\n", fmtv(x.Value), s) + return s +} + +func fmtv(v Value) string { + t := fmt.Sprintf("%T", v) + if i := strings.LastIndex(t, "."); i >= 0 { // strip package + t = t[i+1:] + } + return fmt.Sprintf("%s(%#v)", t, v) +} diff --git a/doc/talks/io2010/talk.pdf b/doc/talks/io2010/talk.pdf Binary files differnew file mode 100644 index 000000000..aff42c21d --- /dev/null +++ b/doc/talks/io2010/talk.pdf diff --git a/doc/talks/io2011/Real_World_Go.pdf b/doc/talks/io2011/Real_World_Go.pdf Binary files differnew file mode 100644 index 000000000..2a187116b --- /dev/null +++ b/doc/talks/io2011/Real_World_Go.pdf diff --git a/doc/talks/io2011/Writing_Web_Apps_in_Go.pdf b/doc/talks/io2011/Writing_Web_Apps_in_Go.pdf Binary files differnew file mode 100644 index 000000000..ca4702ee9 --- /dev/null +++ b/doc/talks/io2011/Writing_Web_Apps_in_Go.pdf diff --git a/doc/talks/java-typing.png b/doc/talks/java-typing.png Binary files differnew file mode 100644 index 000000000..54abf0186 --- /dev/null +++ b/doc/talks/java-typing.png diff --git a/doc/talks/slidy.css b/doc/talks/slidy.css new file mode 100644 index 000000000..e9ff53218 --- /dev/null +++ b/doc/talks/slidy.css @@ -0,0 +1,277 @@ +/* http://www.w3.org/Talks/Tools/Slidy/slidy.css + + Copyright (c) 2005 W3C (MIT, ERCIM, Keio), All Rights Reserved. + W3C liability, trademark, document use and software licensing + rules apply, see: + + http://www.w3.org/Consortium/Legal/copyright-documents + http://www.w3.org/Consortium/Legal/copyright-software +*/ +body +{ + margin: 0 0 0 0; + padding: 0 0 0 0; + width: 100%; + height: 100%; + color: black; + background-color: white; + font-family: "Lucida Sans", "Lucida Grande", Lucida, sans-serif; + font-size: 14pt; +} + +.hidden { display: none; visibility: hidden } + +div.toolbar { + position: fixed; z-index: 200; + top: auto; bottom: 0; left: 0; right: 0; + height: 1.2em; text-align: right; + padding-left: 1em; + padding-right: 1em; + font-size: 60%; + color: red; background: rgb(240,240,240); +} + +div.background { + display: none; +} + +div.handout { + margin-left: 20px; + margin-right: 20px; +} + +div.slide.titlepage { + color: white; + background: black; + text-align: center; +} + +div.slide { + z-index: 20; + margin: 0 0 0 0; + padding-top: 0; + padding-bottom: 0; + padding-left: 20px; + padding-right: 20px; + border-width: 0; + top: 0; + bottom: 0; + left: 0; + right: 0; + line-height: 120%; + background-color: transparent; +} + +/* this rule is hidden from IE 6 and below which don't support + selector */ +div.slide + div[class].slide { page-break-before: always;} + +div.slide h1 { + padding-left: 20px; + padding-right: 20px; + padding-top: 10px; + padding-bottom: 10px; + margin-top: 0; + margin-left: 0; + margin-right: 0; + margin-bottom: 0.5em; + border-bottom: 4px solid #36c; + display: block; + font-size: 160%; + line-height: 1.2em; +} + +div.slide h2 { + font-size:120%; + line-height: 1.2em; +} + +div.toc { + position: absolute; + top: auto; + bottom: 4em; + left: 4em; + right: auto; + width: 60%; + max-width: 30em; + height: 30em; + border: solid thin black; + padding: 1em; + background: rgb(240,240,240); + color: black; + z-index: 300; + overflow: auto; + display: block; + visibility: visible; +} + +div.toc-heading { + width: 100%; + border-bottom: solid 1px rgb(180,180,180); + margin-bottom: 1em; + text-align: center; +} + +pre { + font-size: 120%; + font-weight: bold; + line-height: 140%; + padding-top: 0.2em; + padding-bottom: 0.2em; + padding-left: 1em; + padding-right: 1em; +/* + border-style: solid; + border-left-width: 1em; + border-top-width: thin; + border-right-width: thin; + border-bottom-width: thin; + border-color: #95ABD0; +*/ + color: #0F398D; + background-color: #fff8f8; +} + +@media print { + div.slide { + display: block; + visibility: visible; + position: relative; + border-top-style: solid; + border-top-width: thin; + border-top-color: black; + } + div.slide pre { font-size: 60%; padding-left: 0.5em; } + div.handout { display: block; visibility: visible; } +} + +blockquote { font-style: italic } + +img { background-color: transparent } + +p.copyright { font-size: smaller } + +.center { text-align: center } +.footnote { font-size: smaller; margin-left: 2em; } + +a img { border-width: 0; border-style: none } + +a:visited { color: navy } +a:link { color: navy } +a:hover { color: red; text-decoration: underline } +a:active { color: red; text-decoration: underline } + +a {text-decoration: none} +.navbar a:link {color: white} +.navbar a:visited {color: yellow} +.navbar a:active {color: red} +.navbar a:hover {color: red} + +ul { list-style-type: square; } +ul ul { list-style-type: disc; } +ul ul ul { list-style-type: circle; } +ul ul ul ul { list-style-type: disc; } +li { margin-left: 2em; margin-top: 0.5em; } +li li { font-size: 85%; font-style: italic } +li li li { font-size: 85%; font-style: normal } + +div dt +{ + margin-left: 0; + margin-top: 1em; + margin-bottom: 0.5em; + font-weight: bold; +} +div dd +{ + margin-left: 2em; + margin-bottom: 0.5em; +} + + +p,pre,ul,ol,blockquote,h2,h3,h4,h5,h6,dl,table { + margin-left: 1em; + margin-right: 1em; +} + +p.subhead { font-weight: bold; margin-top: 2em; } + +p.smaller { font-size: smaller } + +td,th { padding: 0.2em } + +ul { + margin: 0.5em 1.5em 0.5em 1.5em; + padding: 0; +} + +ol { + margin: 0.5em 1.5em 0.5em 1.5em; + padding: 0; +} + +ul { list-style-type: square; } +ul ul { list-style-type: disc; } +ul ul ul { list-style-type: circle; } +ul ul ul ul { list-style-type: disc; } + +ul li { + list-style: square; + //margin: 0.1em 0em 0.6em 0; + padding: 0 0 0 0; + line-height: 140%; +} + +ol li { + margin: 0.1em 0em 0.6em 1.5em; + padding: 0 0 0 0px; + line-height: 140%; + list-style-type: decimal; +} + +li ul li { + font-size: 85%; + font-style: italic; + list-style-type: disc; + background: transparent; + padding: 0 0 0 0; +} +li li ul li { + font-size: 85%; + font-style: normal; + list-style-type: circle; + background: transparent; + padding: 0 0 0 0; +} +li li li ul li { + list-style-type: disc; + background: transparent; + padding: 0 0 0 0; +} + +li ol li { + list-style-type: decimal; +} + + +li li ol li { + list-style-type: decimal; +} + +/* + setting class="outline on ol or ul makes it behave as an + ouline list where blocklevel content in li elements is + hidden by default and can be expanded or collapsed with + mouse click. Set class="expand" on li to override default +*/ + +ol.outline li:hover { cursor: pointer } +ol.outline li.nofold:hover { cursor: default } + +ul.outline li:hover { cursor: pointer } +ul.outline li.nofold:hover { cursor: default } + +ol.outline { list-style:decimal; } +ol.outline ol { list-style-type:lower-alpha } + +/* for slides with class "title" in table of contents */ +a.titleslide { font-weight: bold; font-style: italic } diff --git a/doc/talks/slidy.js b/doc/talks/slidy.js new file mode 100644 index 000000000..6a5561a6c --- /dev/null +++ b/doc/talks/slidy.js @@ -0,0 +1,2772 @@ +/* http://www.w3.org/Talks/Tools/Slidy/slidy.js + + Copyright (c) 2005 W3C (MIT, ERCIM, Keio), All Rights Reserved. + W3C liability, trademark, document use and software licensing + rules apply, see: + + http://www.w3.org/Consortium/Legal/copyright-documents + http://www.w3.org/Consortium/Legal/copyright-software +*/ + +var ns_pos = (typeof window.pageYOffset!='undefined'); +var khtml = ((navigator.userAgent).indexOf("KHTML") >= 0 ? true : false); +var opera = ((navigator.userAgent).indexOf("Opera") >= 0 ? true : false); +var ie7 = (!ns_pos && navigator.userAgent.indexOf("MSIE 7") != -1); + +window.onload = startup; // equivalent to onload on body element + +// IE only event handlers to ensure all slides are printed +// I don't yet know how to emulate these for other browsers +window.onbeforeprint = beforePrint; +window.onafterprint = afterPrint; + +// hack to hide slides while loading +setTimeout(hideAll, 50); + +function hideAll() +{ + if (document.body) + document.body.style.visibility = "hidden"; + else + setTimeout(hideAll, 50); +} + +var slidenum = 0; // integer slide count: 0, 1, 2, ... +var slides; // set to array of slide div's +var slideNumElement; // element containing slide number +var notes; // set to array of handout div's +var backgrounds; // set to array of background div's +var toolbar; // element containing toolbar +var title; // document title +var lastShown = null; // last incrementally shown item +var eos = null; // span element for end of slide indicator +var toc = null; // table of contents +var outline = null; // outline element with the focus +var selectedTextLen; // length of drag selection on document + +var viewAll = 0; // 1 to view all slides + handouts +var wantToolbar = 1; // 0 if toolbar isn't wanted +var mouseClickEnabled = true; // enables left click for next slide +var scrollhack = 0; // IE work around for position: fixed + +var helpAnchor; // used for keyboard focus hack in showToolbar() +var helpPage = "http://www.w3.org/Talks/Tools/Slidy/help.html"; +var helpText = "Navigate with mouse click, space bar, Cursor Left/Right, " + + "or Pg Up and Pg Dn. Use S and B to change font size."; + +var sizeIndex = 0; +var sizeAdjustment = 0; +var sizes = new Array("10pt", "12pt", "14pt", "16pt", "18pt", "20pt", + "22pt", "24pt", "26pt", "28pt", "30pt", "32pt"); + +var okayForIncremental = incrementalElementList(); + +// needed for efficient resizing +var lastWidth = 0; +var lastHeight = 0; + +// Needed for cross browser support for relative width/height on +// object elements. The work around is to save width/height attributes +// and then to recompute absolute width/height dimensions on resizing +var objects; + +// updated to language specified by html file +var lang = "en"; + +//var localize = {}; + +// for each language there is an associative array +var strings_es = { + "slide":"pág.", + "help?":"Ayuda", + "contents?":"Índice", + "table of contents":"tabla de contenidos", + "Table of Contents":"Tabla de Contenidos", + "restart presentation":"Reiniciar presentación", + "restart?":"Inicio" + }; + +strings_es[helpText] = + "Utilice el ratón, barra espaciadora, teclas Izda/Dhca, " + + "o Re pág y Av pág. Use S y B para cambiar el tamaño de fuente."; + +var strings_nl = { + "slide":"pagina", + "help?":"Help?", + "contents?":"Inhoud?", + "table of contents":"inhoudsopgave", + "Table of Contents":"Inhoudsopgave", + "restart presentation":"herstart presentatie", + "restart?":"Herstart?" + }; + +strings_nl[helpText] = + "Navigeer d.m.v. het muis, spatiebar, Links/Rechts toetsen, " + + "of PgUp en PgDn. Gebruik S en B om de karaktergrootte te veranderen."; + +var strings_de = { + "slide":"Seite", + "help?":"Hilfe", + "contents?":"Übersicht", + "table of contents":"Inhaltsverzeichnis", + "Table of Contents":"Inhaltsverzeichnis", + "restart presentation":"Präsentation neu starten", + "restart?":"Neustart" + }; + +strings_de[helpText] = + "Benutzen Sie die Maus, Leerschlag, die Cursortasten links/rechts" + + "oder Page up/Page Down zum Wechseln der Seiten und S und B für die Schriftgrösse."; + +var strings_pl = { + "slide":"slajd", + "help?":"pomoc?", + "contents?":"spis treści?", + "table of contents":"spis treści", + "Table of Contents":"Spis Treści", + "restart presentation":"Restartuj prezentację", + "restart?":"restart?" + }; + +strings_pl[helpText] = + "Zmieniaj slajdy klikając myszą, naciskając spację, strzałki lewo/prawo" + + "lub PgUp / PgDn. Użyj klawiszy S i B, aby zmienić rozmiar czczionki."; + +var strings_fr = { + "slide":"page", + "help?":"Aide", + "contents?":"Index", + "table of contents":"table des matières", + "Table of Contents":"Table des matières", + "restart presentation":"Recommencer l'exposé", + "restart?":"Début" + }; + +strings_fr[helpText] = + "Naviguez avec la souris, la barre d'espace, les flèches" + + "gauche/droite ou les touches Pg Up, Pg Dn. Utilisez " + + "les touches S et B pour modifier la taille de la police."; + +var strings_hu = { + "slide":"oldal", + "help?":"segítség", + "contents?":"tartalom", + "table of contents":"tartalomjegyzék", + "Table of Contents":"Tartalomjegyzék", + "restart presentation":"bemutató újraindítása", + "restart?":"újraindítás" + }; + +strings_hu[helpText] = + "Az oldalak közti lépkedéshez kattintson az egérrel, vagy használja a szóköz, a bal, vagy a jobb nyíl, " + + "illetve a Page Down, Page Up billentyűket. Az S és a B billentyűkkel változtathatja a szöveg méretét."; + +var strings_it = { + "slide":"pag.", + "help?":"Aiuto", + "contents?":"Indice", + "table of contents":"indice", + "Table of Contents":"Indice", + "restart presentation":"Ricominciare la presentazione", + "restart?":"Inizio" + }; + +strings_it[helpText] = + "Navigare con mouse, barra spazio, frecce sinistra/destra o " + + "PgUp e PgDn. Usare S e B per cambiare la dimensione dei caratteri."; + +var strings_el = { + "slide":"σελίδα", + "help?":"βοήθεια;", + "contents?":"περιεχόμενα;", + "table of contents":"πίνακας περιεχομένων", + "Table of Contents":"Πίνακας Περιεχομένων", + "restart presentation":"επανεκκίνηση παρουσίασης", + "restart?":"επανεκκίνηση;" + }; + +strings_el[helpText] = + "Πλοηγηθείτε με το κλίκ του ποντικιού, το space, τα βέλη αριστερά/δεξιά, " + + "ή Page Up και Page Down. Χρησιμοποιήστε τα πλήκτρα S και B για να αλλάξετε " + + "το μέγεθος της γραμματοσειράς."; + +var strings_ja = { + "slide":"スライド", + "help?":"ヘルプ", + "contents?":"目次", + "table of contents":"目次を表示", + "Table of Contents":"目次", + "restart presentation":"最初から再生", + "restart?":"最初から" +}; + +strings_ja[helpText] = + "マウス左クリック ・ スペース ・ 左右キー " + + "または Page Up ・ Page Downで操作, S ・ Bでフォントサイズ変更"; + + +// each such language array is declared in the localize array +// used indirectly as in help.innerHTML = "help".localize(); +var localize = { + "es":strings_es, + "nl":strings_nl, + "de":strings_de, + "pl":strings_pl, + "fr":strings_fr, + "hu":strings_hu, + "it":strings_it, + "el":strings_el, + "jp":strings_ja + }; + +/* general initialization */ +function startup() +{ + // find human language from html element + // for use in localizing strings + lang = document.body.parentNode.getAttribute("lang"); + + if (!lang) + lang = document.body.parentNode.getAttribute("xml:lang"); + + if (!lang) + lang = "en"; + + document.body.style.visibility = "visible"; + title = document.title; + toolbar = addToolbar(); + wrapImplicitSlides(); + slides = collectSlides(); + notes = collectNotes(); + objects = document.body.getElementsByTagName("object"); + backgrounds = collectBackgrounds(); + patchAnchors(); + + slidenum = findSlideNumber(location.href); + window.offscreenbuffering = true; + sizeAdjustment = findSizeAdjust(); + hideImageToolbar(); // suppress IE image toolbar popup + initOutliner(); // activate fold/unfold support + + if (slides.length > 0) + { + var slide = slides[slidenum]; + slide.style.position = "absolute"; + + if (slidenum > 0) + { + setVisibilityAllIncremental("visible"); + lastShown = previousIncrementalItem(null); + setEosStatus(true); + } + else + { + lastShown = null; + setVisibilityAllIncremental("hidden"); + setEosStatus(!nextIncrementalItem(lastShown)); + } + + setLocation(); + } + + toc = tableOfContents(); + hideTableOfContents(); + + // bind event handlers + document.onclick = mouseButtonClick; + document.onmouseup = mouseButtonUp; + document.onkeydown = keyDown; + window.onresize = resized; + window.onscroll = scrolled; + singleSlideView(); + + setLocation(); + resized(); + + if (ie7) + setTimeout("ieHack()", 100); + + showToolbar(); +} + +// add localize method to all strings for use +// as in help.innerHTML = "help".localize(); +String.prototype.localize = function() +{ + if (this == "") + return this; + + // try full language code, e.g. en-US + var s, lookup = localize[lang]; + + if (lookup) + { + s = lookup[this]; + + if (s) + return s; + } + + // try en if undefined for en-US + var lg = lang.split("-"); + + if (lg.length > 1) + { + lookup = localize[lg[0]]; + + if (lookup) + { + s = lookup[this]; + + if (s) + return s; + } + } + + // otherwise string as is + return this; +} + +// suppress IE's image toolbar pop up +function hideImageToolbar() +{ + if (!ns_pos) + { + var images = document.getElementsByTagName("IMG"); + + for (var i = 0; i < images.length; ++i) + images[i].setAttribute("galleryimg", "no"); + } +} + +// hack to persuade IE to compute correct document height +// as needed for simulating fixed positioning of toolbar +function ieHack() +{ + window.resizeBy(0,-1); + window.resizeBy(0, 1); +} + +// Firefox reload SVG bug work around +function reload(e) +{ + if (!e) + var e = window.event; + + hideBackgrounds(); + setTimeout("document.reload();", 100); + + stopPropagation(e); + e.cancel = true; + e.returnValue = false; + + return false; +} + +// Safari and Konqueror don't yet support getComputedStyle() +// and they always reload page when location.href is updated +function isKHTML() +{ + var agent = navigator.userAgent; + return (agent.indexOf("KHTML") >= 0 ? true : false); +} + +function resized() +{ + var width = 0; + + if ( typeof( window.innerWidth ) == 'number' ) + width = window.innerWidth; // Non IE browser + else if (document.documentElement && document.documentElement.clientWidth) + width = document.documentElement.clientWidth; // IE6 + else if (document.body && document.body.clientWidth) + width = document.body.clientWidth; // IE4 + + var height = 0; + + if ( typeof( window.innerHeight ) == 'number' ) + height = window.innerHeight; // Non IE browser + else if (document.documentElement && document.documentElement.clientHeight) + height = document.documentElement.clientHeight; // IE6 + else if (document.body && document.body.clientHeight) + height = document.body.clientHeight; // IE4 + + if (height && (width/height > 1.05*1024/768)) + { + width = height * 1024.0/768; + } + + // IE fires onresize even when only font size is changed! + // so we do a check to avoid blocking < and > actions + if (width != lastWidth || height != lastHeight) + { + if (width >= 1100) + sizeIndex = 5; // 4 + else if (width >= 1000) + sizeIndex = 4; // 3 + else if (width >= 800) + sizeIndex = 3; // 2 + else if (width >= 600) + sizeIndex = 2; // 1 + else if (width) + sizeIndex = 0; + + // add in font size adjustment from meta element e.g. + // <meta name="font-size-adjustment" content="-2" /> + // useful when slides have too much content ;-) + + if (0 <= sizeIndex + sizeAdjustment && + sizeIndex + sizeAdjustment < sizes.length) + sizeIndex = sizeIndex + sizeAdjustment; + + // enables cross browser use of relative width/height + // on object elements for use with SVG and Flash media + adjustObjectDimensions(width, height); + + document.body.style.fontSize = sizes[sizeIndex]; + + lastWidth = width; + lastHeight = height; + + // force reflow to work around Mozilla bug + //if (ns_pos) + { + var slide = slides[slidenum]; + hideSlide(slide); + showSlide(slide); + } + + // force correct positioning of toolbar + refreshToolbar(200); + } +} + +function scrolled() +{ + if (toolbar && !ns_pos && !ie7) + { + hackoffset = scrollXOffset(); + // hide toolbar + toolbar.style.display = "none"; + + // make it reappear later + if (scrollhack == 0 && !viewAll) + { + setTimeout(showToolbar, 1000); + scrollhack = 1; + } + } +} + +// used to ensure IE refreshes toolbar in correct position +function refreshToolbar(interval) +{ + if (!ns_pos && !ie7) + { + hideToolbar(); + setTimeout(showToolbar, interval); + } +} + +// restores toolbar after short delay +function showToolbar() +{ + if (wantToolbar) + { + if (!ns_pos) + { + // adjust position to allow for scrolling + var xoffset = scrollXOffset(); + toolbar.style.left = xoffset; + toolbar.style.right = xoffset; + + // determine vertical scroll offset + //var yoffset = scrollYOffset(); + + // bottom is doc height - window height - scroll offset + //var bottom = documentHeight() - lastHeight - yoffset + + //if (yoffset > 0 || documentHeight() > lastHeight) + // bottom += 16; // allow for height of scrollbar + + toolbar.style.bottom = 0; //bottom; + } + + toolbar.style.display = "block"; + toolbar.style.visibility = "visible"; + } + + scrollhack = 0; + + + // set the keyboard focus to the help link on the + // toolbar to ensure that document has the focus + // IE doesn't always work with window.focus() + // and this hack has benefit of Enter for help + + try + { + if (!opera) + helpAnchor.focus(); + } + catch (e) + { + } +} + +function test() +{ + var s = "docH: " + documentHeight() + + " winH: " + lastHeight + + " yoffset: " + scrollYOffset() + + " toolbot: " + (documentHeight() - lastHeight - scrollYOffset()); + + //alert(s); + + var slide = slides[slidenum]; + // IE getAttribute requires "class" to be "className" + var name = ns_pos ? "class" : "className"; + var style = (slide.currentStyle ? slide.currentStyle["backgroundColor"] : + document.defaultView.getComputedStyle(slide, '').getPropertyValue("background-color")); + alert("class='" + slide.getAttribute(name) + "' backgroundColor: " + style); +} + +function hideToolbar() +{ + toolbar.style.display = "none"; + toolbar.style.visibility = "hidden"; + window.focus(); +} + +// invoked via F key +function toggleToolbar() +{ + if (!viewAll) + { + if (toolbar.style.display == "none") + { + toolbar.style.display = "block"; + toolbar.style.visibility = "visible"; + wantToolbar = 1; + } + else + { + toolbar.style.display = "none"; + toolbar.style.visibility = "hidden"; + wantToolbar = 0; + } + } +} + +function scrollXOffset() +{ + if (window.pageXOffset) + return self.pageXOffset; + + if (document.documentElement && + document.documentElement.scrollLeft) + return document.documentElement.scrollLeft; + + if (document.body) + return document.body.scrollLeft; + + return 0; +} + + +function scrollYOffset() +{ + if (window.pageYOffset) + return self.pageYOffset; + + if (document.documentElement && + document.documentElement.scrollTop) + return document.documentElement.scrollTop; + + if (document.body) + return document.body.scrollTop; + + return 0; +} + +// looking for a way to determine height of slide content +// the slide itself is set to the height of the window +function optimizeFontSize() +{ + var slide = slides[slidenum]; + + //var dh = documentHeight(); //getDocHeight(document); + var dh = slide.scrollHeight; + var wh = getWindowHeight(); + var u = 100 * dh / wh; + + alert("window utilization = " + u + "% (doc " + + dh + " win " + wh + ")"); +} + +function getDocHeight(doc) // from document object +{ + if (!doc) + doc = document; + + if (doc && doc.body && doc.body.offsetHeight) + return doc.body.offsetHeight; // ns/gecko syntax + + if (doc && doc.body && doc.body.scrollHeight) + return doc.body.scrollHeight; + + alert("couldn't determine document height"); +} + +function getWindowHeight() +{ + if ( typeof( window.innerHeight ) == 'number' ) + return window.innerHeight; // Non IE browser + + if (document.documentElement && document.documentElement.clientHeight) + return document.documentElement.clientHeight; // IE6 + + if (document.body && document.body.clientHeight) + return document.body.clientHeight; // IE4 +} + + + +function documentHeight() +{ + var sh, oh; + + sh = document.body.scrollHeight; + oh = document.body.offsetHeight; + + if (sh && oh) + { + return (sh > oh ? sh : oh); + } + + // no idea! + return 0; +} + +function smaller() +{ + if (sizeIndex > 0) + { + --sizeIndex; + } + + toolbar.style.display = "none"; + document.body.style.fontSize = sizes[sizeIndex]; + var slide = slides[slidenum]; + hideSlide(slide); + showSlide(slide); + setTimeout(showToolbar, 300); +} + +function bigger() +{ + if (sizeIndex < sizes.length - 1) + { + ++sizeIndex; + } + + toolbar.style.display = "none"; + document.body.style.fontSize = sizes[sizeIndex]; + var slide = slides[slidenum]; + hideSlide(slide); + showSlide(slide); + setTimeout(showToolbar, 300); +} + +// enables cross browser use of relative width/height +// on object elements for use with SVG and Flash media +// with thanks to Ivan Herman for the suggestion +function adjustObjectDimensions(width, height) +{ + for( var i = 0; i < objects.length; i++ ) + { + var obj = objects[i]; + var mimeType = obj.getAttribute("type"); + + if (mimeType == "image/svg+xml" || mimeType == "application/x-shockwave-flash") + { + if ( !obj.initialWidth ) + obj.initialWidth = obj.getAttribute("width"); + + if ( !obj.initialHeight ) + obj.initialHeight = obj.getAttribute("height"); + + if ( obj.initialWidth && obj.initialWidth.charAt(obj.initialWidth.length-1) == "%" ) + { + var w = parseInt(obj.initialWidth.slice(0, obj.initialWidth.length-1)); + var newW = width * (w/100.0); + obj.setAttribute("width",newW); + } + + if ( obj.initialHeight && obj.initialHeight.charAt(obj.initialHeight.length-1) == "%" ) + { + var h = parseInt(obj.initialHeight.slice(0, obj.initialHeight.length-1)); + var newH = height * (h/100.0); + obj.setAttribute("height", newH); + } + } + } +} + +function cancel(event) +{ + if (event) + { + event.cancel = true; + event.returnValue = false; + + if (event.preventDefault) + event.preventDefault(); + } + + return false; +} + +// See e.g. http://www.quirksmode.org/js/events/keys.html for keycodes +function keyDown(event) +{ + var key; + + if (!event) + var event = window.event; + + // kludge around NS/IE differences + if (window.event) + key = window.event.keyCode; + else if (event.which) + key = event.which; + else + return true; // Yikes! unknown browser + + // ignore event if key value is zero + // as for alt on Opera and Konqueror + if (!key) + return true; + + // check for concurrent control/command/alt key + // but are these only present on mouse events? + + if (event.ctrlKey || event.altKey || event.metaKey) + return true; + + // dismiss table of contents if visible + if (isShownToc() && key != 9 && key != 16 && key != 38 && key != 40) + { + hideTableOfContents(); + + if (key == 27 || key == 84 || key == 67) + return cancel(event); + } + + if (key == 34) // Page Down + { + nextSlide(false); + return cancel(event); + } + else if (key == 33) // Page Up + { + previousSlide(false); + return cancel(event); + } + else if (key == 32) // space bar + { + nextSlide(true); + return cancel(event); + } + else if (key == 37 || key == 38) // Left arrow || Up arrow + { + previousSlide(!event.shiftKey); + return cancel(event); + } + else if (key == 36) // Home + { + firstSlide(); + return cancel(event); + } + else if (key == 35) // End + { + lastSlide(); + return cancel(event); + } + else if (key == 39 || key == 40) // Right arrow || Down arrow + { + nextSlide(!event.shiftKey); + return cancel(event); + } + else if (key == 13) // Enter + { + if (outline) + { + if (outline.visible) + fold(outline); + else + unfold(outline); + + return cancel(event); + } + } + else if (key == 188) // < for smaller fonts + { + smaller(); + return cancel(event); + } + else if (key == 190) // > for larger fonts + { + bigger(); + return cancel(event); + } + else if (key == 189 || key == 109) // - for smaller fonts + { + smaller(); + return cancel(event); + } + else if (key == 187 || key == 191 || key == 107) // = + for larger fonts + { + bigger(); + return cancel(event); + } + else if (key == 83) // S for smaller fonts + { + smaller(); + return cancel(event); + } + else if (key == 66) // B for larger fonts + { + bigger(); + return cancel(event); + } + else if (key == 90) // Z for last slide + { + lastSlide(); + return cancel(event); + } + else if (key == 70) // F for toggle toolbar + { + toggleToolbar(); + return cancel(event); + } + else if (key == 65) // A for toggle view single/all slides + { + toggleView(); + return cancel(event); + } + else if (key == 75) // toggle action of left click for next page + { + mouseClickEnabled = !mouseClickEnabled; + alert((mouseClickEnabled ? "enabled" : "disabled") + " mouse click advance"); + return cancel(event); + } + else if (key == 84 || key == 67) // T or C for table of contents + { + if (toc) + showTableOfContents(); + + return cancel(event); + } + else if (key == 72) // H for help + { + window.location = helpPage; + return cancel(event); + } + + //else if (key == 93) // Windows menu key + //alert("lastShown is " + lastShown); + //else alert("key code is "+ key); + + + return true; +} + +// make note of length of selected text +// as this evaluates to zero in click event +function mouseButtonUp(e) +{ + selectedTextLen = getSelectedText().length; +} + +// right mouse button click is reserved for context menus +// it is more reliable to detect rightclick than leftclick +function mouseButtonClick(e) +{ + var rightclick = false; + var leftclick = false; + var middleclick = false; + var target; + + if (!e) + var e = window.event; + + if (e.target) + target = e.target; + else if (e.srcElement) + target = e.srcElement; + + // work around Safari bug + if (target.nodeType == 3) + target = target.parentNode; + + if (e.which) // all browsers except IE + { + leftclick = (e.which == 1); + middleclick = (e.which == 2); + rightclick = (e.which == 3); + } + else if (e.button) + { + // Konqueror gives 1 for left, 4 for middle + // IE6 gives 0 for left and not 1 as I expected + + if (e.button == 4) + middleclick = true; + + // all browsers agree on 2 for right button + rightclick = (e.button == 2); + } + else leftclick = true; + + // dismiss table of contents + hideTableOfContents(); + + if (selectedTextLen > 0) + { + stopPropagation(e); + e.cancel = true; + e.returnValue = false; + return false; + } + + // check if target is something that probably want's clicks + // e.g. embed, object, input, textarea, select, option + + if (mouseClickEnabled && leftclick && + target.nodeName != "EMBED" && + target.nodeName != "OBJECT" && + target.nodeName != "INPUT" && + target.nodeName != "TEXTAREA" && + target.nodeName != "SELECT" && + target.nodeName != "OPTION") + { + nextSlide(true); + stopPropagation(e); + e.cancel = true; + e.returnValue = false; + } +} + +function previousSlide(incremental) +{ + if (!viewAll) + { + var slide; + + if ((incremental || slidenum == 0) && lastShown != null) + { + lastShown = hidePreviousItem(lastShown); + setEosStatus(false); + } + else if (slidenum > 0) + { + slide = slides[slidenum]; + hideSlide(slide); + + slidenum = slidenum - 1; + slide = slides[slidenum]; + setVisibilityAllIncremental("visible"); + lastShown = previousIncrementalItem(null); + setEosStatus(true); + showSlide(slide); + } + + setLocation(); + + if (!ns_pos) + refreshToolbar(200); + } +} + +function nextSlide(incremental) +{ + if (!viewAll) + { + var slide, last = lastShown; + + if (incremental || slidenum == slides.length - 1) + lastShown = revealNextItem(lastShown); + + if ((!incremental || lastShown == null) && slidenum < slides.length - 1) + { + slide = slides[slidenum]; + hideSlide(slide); + + slidenum = slidenum + 1; + slide = slides[slidenum]; + lastShown = null; + setVisibilityAllIncremental("hidden"); + showSlide(slide); + } + else if (!lastShown) + { + if (last && incremental) + lastShown = last; + } + + setLocation(); + + setEosStatus(!nextIncrementalItem(lastShown)); + + if (!ns_pos) + refreshToolbar(200); + } +} + +// to first slide with nothing revealed +// i.e. state at start of presentation +function firstSlide() +{ + if (!viewAll) + { + var slide; + + if (slidenum != 0) + { + slide = slides[slidenum]; + hideSlide(slide); + + slidenum = 0; + slide = slides[slidenum]; + lastShown = null; + setVisibilityAllIncremental("hidden"); + showSlide(slide); + } + + setEosStatus(!nextIncrementalItem(lastShown)); + setLocation(); + } +} + + +// to last slide with everything revealed +// i.e. state at end of presentation +function lastSlide() +{ + if (!viewAll) + { + var slide; + + lastShown = null; //revealNextItem(lastShown); + + if (lastShown == null && slidenum < slides.length - 1) + { + slide = slides[slidenum]; + hideSlide(slide); + slidenum = slides.length - 1; + slide = slides[slidenum]; + setVisibilityAllIncremental("visible"); + lastShown = previousIncrementalItem(null); + + showSlide(slide); + } + else + { + setVisibilityAllIncremental("visible"); + lastShown = previousIncrementalItem(null); + } + + setEosStatus(true); + setLocation(); + } +} + +function setEosStatus(state) +{ + if (eos) + eos.style.color = (state ? "rgb(240,240,240)" : "red"); +} + +function showSlide(slide) +{ + syncBackground(slide); + window.scrollTo(0,0); + slide.style.visibility = "visible"; + slide.style.display = "block"; +} + +function hideSlide(slide) +{ + slide.style.visibility = "hidden"; + slide.style.display = "none"; +} + +function beforePrint() +{ + showAllSlides(); + hideToolbar(); +} + +function afterPrint() +{ + if (!viewAll) + { + singleSlideView(); + showToolbar(); + } +} + +function printSlides() +{ + beforePrint(); + window.print(); + afterPrint(); +} + +function toggleView() +{ + if (viewAll) + { + singleSlideView(); + showToolbar(); + viewAll = 0; + } + else + { + showAllSlides(); + hideToolbar(); + viewAll = 1; + } +} + +// prepare for printing +function showAllSlides() +{ + var slide; + + for (var i = 0; i < slides.length; ++i) + { + slide = slides[i]; + + slide.style.position = "relative"; + slide.style.borderTopStyle = "solid"; + slide.style.borderTopWidth = "thin"; + slide.style.borderTopColor = "black"; + + try { + if (i == 0) + slide.style.pageBreakBefore = "avoid"; + else + slide.style.pageBreakBefore = "always"; + } + catch (e) + { + //do nothing + } + + setVisibilityAllIncremental("visible"); + showSlide(slide); + } + + var note; + + for (var i = 0; i < notes.length; ++i) + { + showSlide(notes[i]); + } + + // no easy way to render background under each slide + // without duplicating the background divs for each slide + // therefore hide backgrounds to avoid messing up slides + hideBackgrounds(); +} + +// restore after printing +function singleSlideView() +{ + var slide; + + for (var i = 0; i < slides.length; ++i) + { + slide = slides[i]; + + slide.style.position = "absolute"; + + if (i == slidenum) + { + slide.style.borderStyle = "none"; + showSlide(slide); + } + else + { + slide.style.borderStyle = "none"; + hideSlide(slide); + } + } + + setVisibilityAllIncremental("visible"); + lastShown = previousIncrementalItem(null); + + var note; + + for (var i = 0; i < notes.length; ++i) + { + hideSlide(notes[i]); + } +} + +// the string str is a whitespace separated list of tokens +// test if str contains a particular token, e.g. "slide" +function hasToken(str, token) +{ + if (str) + { + // define pattern as regular expression + var pattern = /\w+/g; + + // check for matches + // place result in array + var result = str.match(pattern); + + // now check if desired token is present + for (var i = 0; i < result.length; i++) + { + if (result[i] == token) + return true; + } + } + + return false; +} + +function getClassList(element) +{ + if (typeof window.pageYOffset =='undefined') + return element.getAttribute("className"); + + return element.getAttribute("class"); +} + +function hasClass(element, name) +{ + var regexp = new RegExp("(^| )" + name + "\W*"); + + if (regexp.test(getClassList(element))) + return true; + + return false; + +} + +function removeClass(element, name) +{ + // IE getAttribute requires "class" to be "className" + var clsname = ns_pos ? "class" : "className"; + var clsval = element.getAttribute(clsname); + + var regexp = new RegExp("(^| )" + name + "\W*"); + + if (clsval) + { + clsval = clsval.replace(regexp, ""); + element.setAttribute(clsname, clsval); + } +} + +function addClass(element, name) +{ + if (!hasClass(element, name)) + { + // IE getAttribute requires "class" to be "className" + var clsname = ns_pos ? "class" : "className"; + var clsval = element.getAttribute(clsname); + element.setAttribute(clsname, (clsval ? clsval + " " + name : name)); + } +} + +// wysiwyg editors make it hard to use div elements +// e.g. amaya loses the div when you copy and paste +// this function wraps div elements around implicit +// slides which start with an h1 element and continue +// up to the next heading or div element +function wrapImplicitSlides() +{ + var i, heading, node, next, div; + var headings = document.getElementsByTagName("h1"); + + if (!headings) + return; + + for (i = 0; i < headings.length; ++i) + { + heading = headings[i]; + + if (heading.parentNode != document.body) + continue; + + node = heading.nextSibling; + + div = document.createElement("div"); + div.setAttribute((ns_pos ? "class" : "className"), "slide"); + document.body.replaceChild(div, heading); + div.appendChild(heading); + + while (node) + { + if (node.nodeType == 1 && // an element + (node.nodeName == "H1" || + node.nodeName == "h1" || + node.nodeName == "DIV" || + node.nodeName == "div")) + break; + + next = node.nextSibling; + node = document.body.removeChild(node); + div.appendChild(node); + node = next; + } + } +} + +// return new array of all slides +function collectSlides() +{ + var slides = new Array(); + var divs = document.body.getElementsByTagName("div"); + + for (var i = 0; i < divs.length; ++i) + { + div = divs.item(i); + + if (hasClass(div, "slide")) + { + // add slide to collection + slides[slides.length] = div; + + // hide each slide as it is found + div.style.display = "none"; + div.style.visibility = "hidden"; + + // add dummy <br/> at end for scrolling hack + var node1 = document.createElement("br"); + div.appendChild(node1); + var node2 = document.createElement("br"); + div.appendChild(node2); + } + else if (hasClass(div, "background")) + { // work around for Firefox SVG reload bug + // which otherwise replaces 1st SVG graphic with 2nd + div.style.display = "block"; + } + } + + return slides; +} + +// return new array of all <div class="handout"> +function collectNotes() +{ + var notes = new Array(); + var divs = document.body.getElementsByTagName("div"); + + for (var i = 0; i < divs.length; ++i) + { + div = divs.item(i); + + if (hasClass(div, "handout")) + { + // add slide to collection + notes[notes.length] = div; + + // hide handout notes as they are found + div.style.display = "none"; + div.style.visibility = "hidden"; + } + } + + return notes; +} + +// return new array of all <div class="background"> +// including named backgrounds e.g. class="background titlepage" +function collectBackgrounds() +{ + var backgrounds = new Array(); + var divs = document.body.getElementsByTagName("div"); + + for (var i = 0; i < divs.length; ++i) + { + div = divs.item(i); + + if (hasClass(div, "background")) + { + // add slide to collection + backgrounds[backgrounds.length] = div; + + // hide named backgrounds as they are found + // e.g. class="background epilog" + if (getClassList(div) != "background") + { + div.style.display = "none"; + div.style.visibility = "hidden"; + } + } + } + + return backgrounds; +} + +// show just the backgrounds pertinent to this slide +function syncBackground(slide) +{ + var background; + var bgColor; + + if (slide.currentStyle) + bgColor = slide.currentStyle["backgroundColor"]; + else if (document.defaultView) + { + var styles = document.defaultView.getComputedStyle(slide,null); + + if (styles) + bgColor = styles.getPropertyValue("background-color"); + else // broken implementation probably due Safari or Konqueror + { + //alert("defective implementation of getComputedStyle()"); + bgColor = "transparent"; + } + } + else + bgColor == "transparent"; + + if (bgColor == "transparent") + { + var slideClass = getClassList(slide); + + for (var i = 0; i < backgrounds.length; i++) + { + background = backgrounds[i]; + + var bgClass = getClassList(background); + + if (matchingBackground(slideClass, bgClass)) + { + background.style.display = "block"; + background.style.visibility = "visible"; + } + else + { + background.style.display = "none"; + background.style.visibility = "hidden"; + } + } + } + else // forcibly hide all backgrounds + hideBackgrounds(); +} + +function hideBackgrounds() +{ + for (var i = 0; i < backgrounds.length; i++) + { + background = backgrounds[i]; + background.style.display = "none"; + background.style.visibility = "hidden"; + } +} + +// compare classes for slide and background +function matchingBackground(slideClass, bgClass) +{ + if (bgClass == "background") + return true; + + // define pattern as regular expression + var pattern = /\w+/g; + + // check for matches and place result in array + var result = slideClass.match(pattern); + + // now check if desired name is present for background + for (var i = 0; i < result.length; i++) + { + if (hasToken(bgClass, result[i])) + return true; + } + + return false; +} + +// left to right traversal of root's content +function nextNode(root, node) +{ + if (node == null) + return root.firstChild; + + if (node.firstChild) + return node.firstChild; + + if (node.nextSibling) + return node.nextSibling; + + for (;;) + { + node = node.parentNode; + + if (!node || node == root) + break; + + if (node && node.nextSibling) + return node.nextSibling; + } + + return null; +} + +// right to left traversal of root's content +function previousNode(root, node) +{ + if (node == null) + { + node = root.lastChild; + + if (node) + { + while (node.lastChild) + node = node.lastChild; + } + + return node; + } + + if (node.previousSibling) + { + node = node.previousSibling; + + while (node.lastChild) + node = node.lastChild; + + return node; + } + + if (node.parentNode != root) + return node.parentNode; + + return null; +} + +// HTML elements that can be used with class="incremental" +// note that you can also put the class on containers like +// up, ol, dl, and div to make their contents appear +// incrementally. Upper case is used since this is what +// browsers report for HTML node names (text/html). +function incrementalElementList() +{ + var inclist = new Array(); + inclist["P"] = true; + inclist["PRE"] = true; + inclist["LI"] = true; + inclist["BLOCKQUOTE"] = true; + inclist["DT"] = true; + inclist["DD"] = true; + inclist["H2"] = true; + inclist["H3"] = true; + inclist["H4"] = true; + inclist["H5"] = true; + inclist["H6"] = true; + inclist["SPAN"] = true; + inclist["ADDRESS"] = true; + inclist["TABLE"] = true; + inclist["TR"] = true; + inclist["TH"] = true; + inclist["TD"] = true; + inclist["IMG"] = true; + inclist["OBJECT"] = true; + return inclist; +} + +function nextIncrementalItem(node) +{ + var slide = slides[slidenum]; + + for (;;) + { + node = nextNode(slide, node); + + if (node == null || node.parentNode == null) + break; + + if (node.nodeType == 1) // ELEMENT + { + if (node.nodeName == "BR") + continue; + + if (hasClass(node, "incremental") + && okayForIncremental[node.nodeName]) + return node; + + if (hasClass(node.parentNode, "incremental") + && !hasClass(node, "non-incremental")) + return node; + } + } + + return node; +} + +function previousIncrementalItem(node) +{ + var slide = slides[slidenum]; + + for (;;) + { + node = previousNode(slide, node); + + if (node == null || node.parentNode == null) + break; + + if (node.nodeType == 1) + { + if (node.nodeName == "BR") + continue; + + if (hasClass(node, "incremental") + && okayForIncremental[node.nodeName]) + return node; + + if (hasClass(node.parentNode, "incremental") + && !hasClass(node, "non-incremental")) + return node; + } + } + + return node; +} + +// set visibility for all elements on current slide with +// a parent element with attribute class="incremental" +function setVisibilityAllIncremental(value) +{ + var node = nextIncrementalItem(null); + + while (node) + { + node.style.visibility = value; + node = nextIncrementalItem(node); + } +} + +// reveal the next hidden item on the slide +// node is null or the node that was last revealed +function revealNextItem(node) +{ + node = nextIncrementalItem(node); + + if (node && node.nodeType == 1) // an element + node.style.visibility = "visible"; + + return node; +} + + +// exact inverse of revealNextItem(node) +function hidePreviousItem(node) +{ + if (node && node.nodeType == 1) // an element + node.style.visibility = "hidden"; + + return previousIncrementalItem(node); +} + + +/* set click handlers on all anchors */ +function patchAnchors() +{ + var anchors = document.body.getElementsByTagName("a"); + + for (var i = 0; i < anchors.length; ++i) + { + anchors[i].onclick = clickedAnchor; + } +} + +function clickedAnchor(e) +{ + if (!e) + var e = window.event; + + // compare this.href with location.href + // for link to another slide in this doc + + if (pageAddress(this.href) == pageAddress(location.href)) + { + // yes, so find new slide number + var newslidenum = findSlideNumber(this.href); + + if (newslidenum != slidenum) + { + slide = slides[slidenum]; + hideSlide(slide); + slidenum = newslidenum; + slide = slides[slidenum]; + showSlide(slide); + setLocation(); + } + } + else if (this.target == null) + location.href = this.href; + + this.blur(); + stopPropagation(e); +} + +function pageAddress(uri) +{ + var i = uri.indexOf("#"); + + // check if anchor is entire page + + if (i < 0) + return uri; // yes + + return uri.substr(0, i); +} + +function showSlideNumber() +{ + slideNumElement.innerHTML = "slide".localize() + " " + + (slidenum + 1) + "/" + slides.length; +} + +function setLocation() +{ + var uri = pageAddress(location.href); + + //if (slidenum > 0) + uri = uri + "#(" + (slidenum+1) + ")"; + + if (uri != location.href && !khtml) + location.href = uri; + + document.title = title + " (" + (slidenum+1) + ")"; + //document.title = (slidenum+1) + ") " + slideName(slidenum); + + showSlideNumber(); +} + +// find current slide based upon location +// first find target anchor and then look +// for associated div element enclosing it +// finally map that to slide number +function findSlideNumber(uri) +{ + // first get anchor from page location + + var i = uri.indexOf("#"); + + // check if anchor is entire page + + if (i < 0) + return 0; // yes + + var anchor = unescape(uri.substr(i+1)); + + // now use anchor as XML ID to find target + var target = document.getElementById(anchor); + + if (!target) + { + // does anchor look like "(2)" for slide 2 ?? + // where first slide is (1) + var re = /\((\d)+\)/; + + if (anchor.match(re)) + { + var num = parseInt(anchor.substring(1, anchor.length-1)); + + if (num > slides.length) + num = 1; + + if (--num < 0) + num = 0; + + return num; + } + + // accept [2] for backwards compatibility + re = /\[(\d)+\]/; + + if (anchor.match(re)) + { + var num = parseInt(anchor.substring(1, anchor.length-1)); + + if (num > slides.length) + num = 1; + + if (--num < 0) + num = 0; + + return num; + } + + // oh dear unknown anchor + return 0; + } + + // search for enclosing slide + + while (true) + { + // browser coerces html elements to uppercase! + if (target.nodeName.toLowerCase() == "div" && + hasClass(target, "slide")) + { + // found the slide element + break; + } + + // otherwise try parent element if any + + target = target.parentNode; + + if (!target) + { + return 0; // no luck! + } + }; + + for (i = 0; i < slides.length; ++i) + { + if (slides[i] == target) + return i; // success + } + + // oh dear still no luck + return 0; +} + +// find slide name from first h1 element +// default to document title + slide number +function slideName(index) +{ + var name = null; + var slide = slides[index]; + + var heading = findHeading(slide); + + if (heading) + name = extractText(heading); + + if (!name) + name = title + "(" + (index + 1) + ")"; + + name.replace(/\&/g, "&"); + name.replace(/\</g, "<"); + name.replace(/\>/g, ">"); + + return name; +} + +// find first h1 element in DOM tree +function findHeading(node) +{ + if (!node || node.nodeType != 1) + return null; + + if (node.nodeName == "H1" || node.nodeName == "h1") + return node; + + var child = node.firstChild; + + while (child) + { + node = findHeading(child); + + if (node) + return node; + + child = child.nextSibling; + } + + return null; +} + +// recursively extract text from DOM tree +function extractText(node) +{ + if (!node) + return ""; + + // text nodes + if (node.nodeType == 3) + return node.nodeValue; + + // elements + if (node.nodeType == 1) + { + node = node.firstChild; + var text = ""; + + while (node) + { + text = text + extractText(node); + node = node.nextSibling; + } + + return text; + } + + return ""; +} + + +// find copyright text from meta element +function findCopyright() +{ + var name, content; + var meta = document.getElementsByTagName("meta"); + + for (var i = 0; i < meta.length; ++i) + { + name = meta[i].getAttribute("name"); + content = meta[i].getAttribute("content"); + + if (name == "copyright") + return content; + } + + return null; +} + +function findSizeAdjust() +{ + var name, content, offset; + var meta = document.getElementsByTagName("meta"); + + for (var i = 0; i < meta.length; ++i) + { + name = meta[i].getAttribute("name"); + content = meta[i].getAttribute("content"); + + if (name == "font-size-adjustment") + return 1 * content; + } + + return 0; +} + +function addToolbar() +{ + var slideCounter, page; + + var toolbar = createElement("div"); + toolbar.setAttribute("class", "toolbar"); + + if (ns_pos) // a reasonably behaved browser + { + var right = document.createElement("div"); + right.setAttribute("style", "float: right; text-align: right"); + + slideCounter = document.createElement("div") + slideCounter.innerHTML = "slide".localize() + " n/m"; + right.appendChild(slideCounter); + toolbar.appendChild(right); + + var left = document.createElement("div"); + left.setAttribute("style", "text-align: left"); + + // global end of slide indicator + eos = document.createElement("span"); + eos.innerHTML = "* "; + left.appendChild(eos); + + var help = document.createElement("a"); + help.setAttribute("href", helpPage); + help.setAttribute("title", helpText.localize()); + help.innerHTML = "help?".localize(); + left.appendChild(help); + helpAnchor = help; // save for focus hack + + var gap1 = document.createTextNode(" "); + left.appendChild(gap1); + + var contents = document.createElement("a"); + contents.setAttribute("href", "javascript:toggleTableOfContents()"); + contents.setAttribute("title", "table of contents".localize()); + contents.innerHTML = "contents?".localize(); + left.appendChild(contents); + + var gap2 = document.createTextNode(" "); + left.appendChild(gap2); + + var i = location.href.indexOf("#"); + + // check if anchor is entire page + + if (i > 0) + page = location.href.substr(0, i); + else + page = location.href; + + var start = document.createElement("a"); + start.setAttribute("href", page); + start.setAttribute("title", "restart presentation".localize()); + start.innerHTML = "restart?".localize(); +// start.setAttribute("href", "javascript:printSlides()"); +// start.setAttribute("title", "print all slides".localize()); +// start.innerHTML = "print!".localize(); + left.appendChild(start); + + var copyright = findCopyright(); + + if (copyright) + { + var span = document.createElement("span"); + span.innerHTML = copyright; + span.style.color = "black"; + span.style.marginLeft = "4em"; + left.appendChild(span); + } + + toolbar.appendChild(left); + } + else // IE so need to work around its poor CSS support + { + toolbar.style.position = (ie7 ? "fixed" : "absolute"); + toolbar.style.zIndex = "200"; + toolbar.style.width = "99.9%"; + toolbar.style.height = "1.2em"; + toolbar.style.top = "auto"; + toolbar.style.bottom = "0"; + toolbar.style.left = "0"; + toolbar.style.right = "0"; + toolbar.style.textAlign = "left"; + toolbar.style.fontSize = "60%"; + toolbar.style.color = "red"; + toolbar.borderWidth = 0; + toolbar.style.background = "rgb(240,240,240)"; + + // would like to have help text left aligned + // and page counter right aligned, floating + // div's don't work, so instead use nested + // absolutely positioned div's. + + var sp = document.createElement("span"); + sp.innerHTML = " * "; + toolbar.appendChild(sp); + eos = sp; // end of slide indicator + + var help = document.createElement("a"); + help.setAttribute("href", helpPage); + help.setAttribute("title", helpText.localize()); + help.innerHTML = "help?".localize(); + toolbar.appendChild(help); + helpAnchor = help; // save for focus hack + + var gap1 = document.createTextNode(" "); + toolbar.appendChild(gap1); + + var contents = document.createElement("a"); + contents.setAttribute("href", "javascript:toggleTableOfContents()"); + contents.setAttribute("title", "table of contents".localize()); + contents.innerHTML = "contents?".localize(); + toolbar.appendChild(contents); + + var gap2 = document.createTextNode(" "); + toolbar.appendChild(gap2); + + var i = location.href.indexOf("#"); + + // check if anchor is entire page + + if (i > 0) + page = location.href.substr(0, i); + else + page = location.href; + + var start = document.createElement("a"); + start.setAttribute("href", page); + start.setAttribute("title", "restart presentation".localize()); + start.innerHTML = "restart?".localize(); +// start.setAttribute("href", "javascript:printSlides()"); +// start.setAttribute("title", "print all slides".localize()); +// start.innerHTML = "print!".localize(); + toolbar.appendChild(start); + + var copyright = findCopyright(); + + if (copyright) + { + var span = document.createElement("span"); + span.innerHTML = copyright; + span.style.color = "black"; + span.style.marginLeft = "2em"; + toolbar.appendChild(span); + } + + slideCounter = document.createElement("div") + slideCounter.style.position = "absolute"; + slideCounter.style.width = "auto"; //"20%"; + slideCounter.style.height = "1.2em"; + slideCounter.style.top = "auto"; + slideCounter.style.bottom = 0; + slideCounter.style.right = "0"; + slideCounter.style.textAlign = "right"; + slideCounter.style.color = "red"; + slideCounter.style.background = "rgb(240,240,240)"; + + slideCounter.innerHTML = "slide".localize() + " n/m"; + toolbar.appendChild(slideCounter); + } + + // ensure that click isn't passed through to the page + toolbar.onclick = stopPropagation; + document.body.appendChild(toolbar); + slideNumElement = slideCounter; + setEosStatus(false); + + return toolbar; +} + +function isShownToc() +{ + if (toc && toc.style.visible == "visible") + return true; + + return false; +} + +function showTableOfContents() +{ + if (toc) + { + if (toc.style.visibility != "visible") + { + toc.style.visibility = "visible"; + toc.style.display = "block"; + toc.focus(); + + if (ie7 && slidenum == 0) + setTimeout("ieHack()", 100); + } + else + hideTableOfContents(); + } +} + +function hideTableOfContents() +{ + if (toc && toc.style.visibility != "hidden") + { + toc.style.visibility = "hidden"; + toc.style.display = "none"; + + try + { + if (!opera) + helpAnchor.focus(); + } + catch (e) + { + } + } +} + +function toggleTableOfContents() +{ + if (toc) + { + if (toc.style.visible != "visible") + showTableOfContents(); + else + hideTableOfContents(); + } +} + +// called on clicking toc entry +function gotoEntry(e) +{ + var target; + + if (!e) + var e = window.event; + + if (e.target) + target = e.target; + else if (e.srcElement) + target = e.srcElement; + + // work around Safari bug + if (target.nodeType == 3) + target = target.parentNode; + + if (target && target.nodeType == 1) + { + var uri = target.getAttribute("href"); + + if (uri) + { + //alert("going to " + uri); + var slide = slides[slidenum]; + hideSlide(slide); + slidenum = findSlideNumber(uri); + slide = slides[slidenum]; + lastShown = null; + setLocation(); + setVisibilityAllIncremental("hidden"); + setEosStatus(!nextIncrementalItem(lastShown)); + showSlide(slide); + //target.focus(); + + try + { + if (!opera) + helpAnchor.focus(); + } + catch (e) + { + } + } + } + + hideTableOfContents(e); + if (ie7) ieHack(); + stopPropagation(e); + return cancel(e); +} + +// called onkeydown for toc entry +function gotoTocEntry(event) +{ + var key; + + if (!event) + var event = window.event; + + // kludge around NS/IE differences + if (window.event) + key = window.event.keyCode; + else if (event.which) + key = event.which; + else + return true; // Yikes! unknown browser + + // ignore event if key value is zero + // as for alt on Opera and Konqueror + if (!key) + return true; + + // check for concurrent control/command/alt key + // but are these only present on mouse events? + + if (event.ctrlKey || event.altKey) + return true; + + if (key == 13) + { + var uri = this.getAttribute("href"); + + if (uri) + { + //alert("going to " + uri); + var slide = slides[slidenum]; + hideSlide(slide); + slidenum = findSlideNumber(uri); + slide = slides[slidenum]; + lastShown = null; + setLocation(); + setVisibilityAllIncremental("hidden"); + setEosStatus(!nextIncrementalItem(lastShown)); + showSlide(slide); + //target.focus(); + + try + { + if (!opera) + helpAnchor.focus(); + } + catch (e) + { + } + } + + hideTableOfContents(); + if (ie7) ieHack(); + return cancel(event); + } + + if (key == 40 && this.next) + { + this.next.focus(); + return cancel(event); + } + + if (key == 38 && this.previous) + { + this.previous.focus(); + return cancel(event); + } + + return true; +} + +function isTitleSlide(slide) +{ + return hasClass(slide, "title"); +} + +// create div element with links to each slide +function tableOfContents() +{ + var toc = document.createElement("div"); + addClass(toc, "toc"); + //toc.setAttribute("tabindex", "0"); + + var heading = document.createElement("div"); + addClass(heading, "toc-heading"); + heading.innerHTML = "Table of Contents".localize(); + + heading.style.textAlign = "center"; + heading.style.width = "100%"; + heading.style.margin = "0"; + heading.style.marginBottom = "1em"; + heading.style.borderBottomStyle = "solid"; + heading.style.borderBottomColor = "rgb(180,180,180)"; + heading.style.borderBottomWidth = "1px"; + + toc.appendChild(heading); + var previous = null; + + for (var i = 0; i < slides.length; ++i) + { + var title = hasClass(slides[i], "title"); + var num = document.createTextNode((i + 1) + ". "); + + toc.appendChild(num); + + var a = document.createElement("a"); + a.setAttribute("href", "#(" + (i+1) + ")"); + + if (title) + addClass(a, "titleslide"); + + var name = document.createTextNode(slideName(i)); + a.appendChild(name); + a.onclick = gotoEntry; + a.onkeydown = gotoTocEntry; + a.previous = previous; + + if (previous) + previous.next = a; + + toc.appendChild(a); + + if (i == 0) + toc.first = a; + + if (i < slides.length - 1) + { + var br = document.createElement("br"); + toc.appendChild(br); + } + + previous = a; + } + + toc.focus = function () { + if (this.first) + this.first.focus(); + } + + toc.onclick = function (e) { + e||(e=window.event); + hideTableOfContents(); + stopPropagation(e); + + if (e.cancel != undefined) + e.cancel = true; + + if (e.returnValue != undefined) + e.returnValue = false; + + return false; + }; + + toc.style.position = "absolute"; + toc.style.zIndex = "300"; + toc.style.width = "60%"; + toc.style.maxWidth = "30em"; + toc.style.height = "30em"; + toc.style.overflow = "auto"; + toc.style.top = "auto"; + toc.style.right = "auto"; + toc.style.left = "4em"; + toc.style.bottom = "4em"; + toc.style.padding = "1em"; + toc.style.background = "rgb(240,240,240)"; + toc.style.borderStyle = "solid"; + toc.style.borderWidth = "2px"; + toc.style.fontSize = "60%"; + + document.body.insertBefore(toc, document.body.firstChild); + return toc; +} + +function replaceByNonBreakingSpace(str) +{ + for (var i = 0; i < str.length; ++i) + str[i] = 160; +} + + +function initOutliner() +{ + var items = document.getElementsByTagName("LI"); + + for (var i = 0; i < items.length; ++i) + { + var target = items[i]; + + if (!hasClass(target.parentNode, "outline")) + continue; + + target.onclick = outlineClick; + + if (!ns_pos) + { + target.onmouseover = hoverOutline; + target.onmouseout = unhoverOutline; + } + + if (foldable(target)) + { + target.foldable = true; + target.onfocus = function () {outline = this;}; + target.onblur = function () {outline = null;}; + + if (!target.getAttribute("tabindex")) + target.setAttribute("tabindex", "0"); + + if (hasClass(target, "expand")) + unfold(target); + else + fold(target); + } + else + { + addClass(target, "nofold"); + target.visible = true; + target.foldable = false; + } + } +} + +function foldable(item) +{ + if (!item || item.nodeType != 1) + return false; + + var node = item.firstChild; + + while (node) + { + if (node.nodeType == 1 && isBlock(node)) + return true; + + node = node.nextSibling; + } + + return false; +} + +function fold(item) +{ + if (item) + { + removeClass(item, "unfolded"); + addClass(item, "folded"); + } + + var node = item ? item.firstChild : null; + + while (node) + { + if (node.nodeType == 1 && isBlock(node)) // element + { + // note that getElementStyle won't work for Safari 1.3 + node.display = getElementStyle(node, "display", "display"); + node.style.display = "none"; + node.style.visibility = "hidden"; + } + + node = node.nextSibling; + } + + item.visible = false; +} + +function unfold(item) +{ + if (item) + { + addClass(item, "unfolded"); + removeClass(item, "folded"); + } + + var node = item ? item.firstChild : null; + + while (node) + { + if (node.nodeType == 1 && isBlock(node)) // element + { + // with fallback for Safari, see above + node.style.display = (node.display ? node.display : "block"); + node.style.visibility = "visible"; + } + + node = node.nextSibling; + } + + item.visible = true; +} + +function outlineClick(e) +{ + var rightclick = false; + var target; + + if (!e) + var e = window.event; + + if (e.target) + target = e.target; + else if (e.srcElement) + target = e.srcElement; + + // work around Safari bug + if (target.nodeType == 3) + target = target.parentNode; + + while (target && target.visible == undefined) + target = target.parentNode; + + if (!target) + return true; + + if (e.which) + rightclick = (e.which == 3); + else if (e.button) + rightclick = (e.button == 2); + + if (!rightclick && target.visible != undefined) + { + if (target.foldable) + { + if (target.visible) + fold(target); + else + unfold(target); + } + + stopPropagation(e); + e.cancel = true; + e.returnValue = false; + } + + return false; +} + +function hoverOutline(e) +{ + var target; + + if (!e) + var e = window.event; + + if (e.target) + target = e.target; + else if (e.srcElement) + target = e.srcElement; + + // work around Safari bug + if (target.nodeType == 3) + target = target.parentNode; + + while (target && target.visible == undefined) + target = target.parentNode; + + if (target && target.foldable) + target.style.cursor = "pointer"; + + return true; +} + +function unhoverOutline(e) +{ + var target; + + if (!e) + var e = window.event; + + if (e.target) + target = e.target; + else if (e.srcElement) + target = e.srcElement; + + // work around Safari bug + if (target.nodeType == 3) + target = target.parentNode; + + while (target && target.visible == undefined) + target = target.parentNode; + + if (target) + target.style.cursor = "default"; + + return true; +} + + +function stopPropagation(e) +{ + if (window.event) + { + window.event.cancelBubble = true; + //window.event.returnValue = false; + } + else if (e) + { + e.cancelBubble = true; + e.stopPropagation(); + //e.preventDefault(); + } +} + +/* can't rely on display since we set that to none to hide things */ +function isBlock(elem) +{ + var tag = elem.nodeName; + + return tag == "OL" || tag == "UL" || tag == "P" || + tag == "LI" || tag == "TABLE" || tag == "PRE" || + tag == "H1" || tag == "H2" || tag == "H3" || + tag == "H4" || tag == "H5" || tag == "H6" || + tag == "BLOCKQUOTE" || tag == "ADDRESS"; +} + +function getElementStyle(elem, IEStyleProp, CSSStyleProp) +{ + if (elem.currentStyle) + { + return elem.currentStyle[IEStyleProp]; + } + else if (window.getComputedStyle) + { + var compStyle = window.getComputedStyle(elem, ""); + return compStyle.getPropertyValue(CSSStyleProp); + } + return ""; +} + +// works with text/html and text/xhtml+xml with thanks to Simon Willison +function createElement(element) +{ + if (typeof document.createElementNS != 'undefined') + { + return document.createElementNS('http://www.w3.org/1999/xhtml', element); + } + + if (typeof document.createElement != 'undefined') + { + return document.createElement(element); + } + + return false; +} + +// designed to work with both text/html and text/xhtml+xml +function getElementsByTagName(name) +{ + if (typeof document.getElementsByTagNameNS != 'undefined') + { + return document.getElementsByTagNameNS('http://www.w3.org/1999/xhtml', name); + } + + if (typeof document.getElementsByTagName != 'undefined') + { + return document.getElementsByTagName(name); + } + + return null; +} + +/* +// clean alternative to innerHTML method, but on IE6 +// it doesn't work with named entities like +// which need to be replaced by numeric entities +function insertText(element, text) +{ + try + { + element.textContent = text; // DOM3 only + } + catch (e) + { + if (element.firstChild) + { + // remove current children + while (element.firstChild) + element.removeChild(element.firstChild); + } + + element.appendChild(document.createTextNode(text)); + } +} + +// as above, but as method of all element nodes +// doesn't work in IE6 which doesn't allow you to +// add methods to the HTMLElement prototype +if (HTMLElement != undefined) +{ + HTMLElement.prototype.insertText = function(text) { + var element = this; + + try + { + element.textContent = text; // DOM3 only + } + catch (e) + { + if (element.firstChild) + { + // remove current children + while (element.firstChild) + element.removeChild(element.firstChild); + } + + element.appendChild(document.createTextNode(text)); + } + }; +} +*/ + +function getSelectedText() +{ + try + { + if (window.getSelection) + return window.getSelection().toString(); + + if (document.getSelection) + return document.getSelection().toString(); + + if (document.selection) + return document.selection.createRange().text; + } + catch (e) + { + return ""; + } + return ""; +} diff --git a/doc/tmpltohtml.go b/doc/tmpltohtml.go new file mode 100644 index 000000000..f4d2e2c2c --- /dev/null +++ b/doc/tmpltohtml.go @@ -0,0 +1,176 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + + +// The template uses the function "code" to inject program +// source into the output by extracting code from files and +// injecting them as HTML-escaped <pre> blocks. +// +// The syntax is simple: 1, 2, or 3 space-separated arguments: +// +// Whole file: +// {{code "foo.go"}} +// One line (here the signature of main): +// {{code "foo.go" `/^func.main/`}} +// Block of text, determined by start and end (here the body of main): +// {{code "foo.go" `/^func.main/` `/^}/` +// +// Patterns can be `/regular expression/`, a decimal number, or "$" +// to signify the end of the file. +package main + +import ( + "exp/template" + "flag" + "fmt" + "io/ioutil" + "log" + "os" + "regexp" + "strings" +) + +func Usage() { + fmt.Fprintf(os.Stderr, "usage: tmpltohtml file\n") + os.Exit(2) +} + +func main() { + flag.Usage = Usage + flag.Parse() + if len(flag.Args()) != 1 { + Usage() + } + + // Read and parse the input. + name := flag.Args()[0] + tmpl := template.New(name).Funcs(template.FuncMap{"code": code}) + if _, err := tmpl.ParseFile(name); err != nil { + log.Fatal(err) + } + + // Execute the template. + if err := tmpl.Execute(os.Stdout, 0); err != nil { + log.Fatal(err) + } +} + +// contents reads a file by name and returns its contents as a string. +func contents(name string) string { + file, err := ioutil.ReadFile(name) + if err != nil { + log.Fatal(err) + } + return string(file) +} + +// format returns a textual representation of the arg, formatted according to its nature. +func format(arg interface{}) string { + switch arg := arg.(type) { + case int: + return fmt.Sprintf("%d", arg) + case string: + if len(arg) > 2 && arg[0] == '/' && arg[len(arg)-1] == '/' { + return fmt.Sprintf("%#q", arg) + } + return fmt.Sprintf("%q", arg) + default: + log.Fatalf("unrecognized argument: %v type %T", arg, arg) + } + return "" +} + +func code(file string, arg ...interface{}) (string, os.Error) { + text := contents(file) + var command string + switch len(arg) { + case 0: + // text is already whole file. + command = fmt.Sprintf("code %q", file) + case 1: + command = fmt.Sprintf("code %q %s", file, format(arg[0])) + text = oneLine(file, text, arg[0]) + case 2: + command = fmt.Sprintf("code %q %s %s", file, format(arg[0]), format(arg[1])) + text = multipleLines(file, text, arg[0], arg[1]) + default: + return "", fmt.Errorf("incorrect code invocation: code %q %q", file, arg) + } + // Replace tabs by spaces, which work better in HTML. + text = strings.Replace(text, "\t", " ", -1) + // Escape the program text for HTML. + text = template.HTMLEscapeString(text) + // Include the command as a comment. + text = fmt.Sprintf("<pre><!--{{%s}}\n-->%s</pre>", command, text) + return text, nil +} + +// parseArg returns the integer or string value of the argument and tells which it is. +func parseArg(arg interface{}, file string, max int) (ival int, sval string, isInt bool) { + switch n := arg.(type) { + case int: + if n <= 0 || n > max { + log.Fatalf("%q:%d is out of range", file, n) + } + return n, "", true + case string: + return 0, n, false + } + log.Fatalf("unrecognized argument %v type %T", arg, arg) + return +} + +// oneLine returns the single line generated by a two-argument code invocation. +func oneLine(file, text string, arg interface{}) string { + lines := strings.SplitAfter(contents(file), "\n") + line, pattern, isInt := parseArg(arg, file, len(lines)) + if isInt { + return lines[line-1] + } + return lines[match(file, 0, lines, pattern)-1] +} + +// multipleLines returns the text generated by a three-argument code invocation. +func multipleLines(file, text string, arg1, arg2 interface{}) string { + lines := strings.SplitAfter(contents(file), "\n") + line1, pattern1, isInt1 := parseArg(arg1, file, len(lines)) + line2, pattern2, isInt2 := parseArg(arg2, file, len(lines)) + if !isInt1 { + line1 = match(file, 0, lines, pattern1) + } + if !isInt2 { + line2 = match(file, line1, lines, pattern2) + } else if line2 < line1 { + log.Fatal("lines out of order for %q: %d %d", line1, line2) + } + return strings.Join(lines[line1-1:line2], "") +} + +// match identifies the input line that matches the pattern in a code invocation. +// If start>0, match lines starting there rather than at the beginning. +// The return value is 1-indexed. +func match(file string, start int, lines []string, pattern string) int { + // $ matches the end of the file. + if pattern == "$" { + if len(lines) == 0 { + log.Fatal("%q: empty file", file) + } + return len(lines) + } + // /regexp/ matches the line that matches the regexp. + if len(pattern) > 2 && pattern[0] == '/' && pattern[len(pattern)-1] == '/' { + re, err := regexp.Compile(pattern[1 : len(pattern)-1]) + if err != nil { + log.Fatal(err) + } + for i := start; i < len(lines); i++ { + if re.MatchString(lines[i]) { + return i + 1 + } + } + log.Fatalf("%s: no match for %#q", file, pattern) + } + log.Fatalf("unrecognized pattern: %q", pattern) + return 0 +} diff --git a/doc/video-001.png b/doc/video-001.png Binary files differnew file mode 100644 index 000000000..d3468bbe8 --- /dev/null +++ b/doc/video-001.png diff --git a/doc/video-002.png b/doc/video-002.png Binary files differnew file mode 100644 index 000000000..4f7c5d184 --- /dev/null +++ b/doc/video-002.png diff --git a/doc/video-003.png b/doc/video-003.png Binary files differnew file mode 100644 index 000000000..3dff68602 --- /dev/null +++ b/doc/video-003.png diff --git a/doc/video-004.png b/doc/video-004.png Binary files differnew file mode 100644 index 000000000..92144549a --- /dev/null +++ b/doc/video-004.png diff --git a/doc/video-005.jpg b/doc/video-005.jpg Binary files differnew file mode 100644 index 000000000..32371581f --- /dev/null +++ b/doc/video-005.jpg |