diff options
Diffstat (limited to 'doc')
121 files changed, 0 insertions, 30223 deletions
diff --git a/doc/ExpressivenessOfGo.pdf b/doc/ExpressivenessOfGo.pdf Binary files differdeleted file mode 100644 index f1931d081..000000000 --- a/doc/ExpressivenessOfGo.pdf +++ /dev/null diff --git a/doc/GoCourseDay1.pdf b/doc/GoCourseDay1.pdf Binary files differdeleted file mode 100644 index 5a7749c18..000000000 --- a/doc/GoCourseDay1.pdf +++ /dev/null diff --git a/doc/GoCourseDay2.pdf b/doc/GoCourseDay2.pdf Binary files differdeleted file mode 100644 index 0d82ba4d3..000000000 --- a/doc/GoCourseDay2.pdf +++ /dev/null diff --git a/doc/GoCourseDay3.pdf b/doc/GoCourseDay3.pdf Binary files differdeleted file mode 100644 index 5a5463ba2..000000000 --- a/doc/GoCourseDay3.pdf +++ /dev/null diff --git a/doc/Makefile b/doc/Makefile deleted file mode 100644 index d992a39f3..000000000 --- a/doc/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# 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=htmlgen -GOFILES=\ - htmlgen.go\ - -include ../src/Make.cmd diff --git a/doc/all.css b/doc/all.css deleted file mode 100644 index a985d8ffb..000000000 --- a/doc/all.css +++ /dev/null @@ -1,205 +0,0 @@ -/* 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 { - margin-bottom: -0em; - 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 differdeleted file mode 100644 index 86a3b3086..000000000 --- a/doc/button_background.png +++ /dev/null diff --git a/doc/code.html b/doc/code.html deleted file mode 100644 index cdc60b071..000000000 --- a/doc/code.html +++ /dev/null @@ -1,368 +0,0 @@ -<!-- 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 deleted file mode 100644 index 09c3291a0..000000000 --- a/doc/codelab/wiki/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -# 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 deleted file mode 100644 index 7a5768ce9..000000000 --- a/doc/codelab/wiki/edit.html +++ /dev/null @@ -1,6 +0,0 @@ -<h1>Editing {Title}</h1> - -<form action="/save/{Title}" method="POST"> -<div><textarea name="body" rows="20" cols="80">{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 deleted file mode 100644 index d09a0d7ab..000000000 --- a/doc/codelab/wiki/final-noclosure.go +++ /dev/null @@ -1,100 +0,0 @@ -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", 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 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 deleted file mode 100644 index 5fcf1de76..000000000 --- a/doc/codelab/wiki/final-noerror.go +++ /dev/null @@ -1,52 +0,0 @@ -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", nil) - 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", nil) - 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 deleted file mode 100644 index f25012eed..000000000 --- a/doc/codelab/wiki/final-parsetemplate.go +++ /dev/null @@ -1,90 +0,0 @@ -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 deleted file mode 100644 index aab536ee1..000000000 --- a/doc/codelab/wiki/final-template.go +++ /dev/null @@ -1,64 +0,0 @@ -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 deleted file mode 100644 index c97a699d4..000000000 --- a/doc/codelab/wiki/final.go +++ /dev/null @@ -1,93 +0,0 @@ -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"} { - templates[tmpl] = template.MustParseFile(tmpl+".html", nil) - } -} - -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 deleted file mode 100644 index c36684e3e..000000000 --- a/doc/codelab/wiki/get.go +++ /dev/null @@ -1,50 +0,0 @@ -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 deleted file mode 100644 index 456d06fd5..000000000 --- a/doc/codelab/wiki/htmlify.go +++ /dev/null @@ -1,12 +0,0 @@ -package main - -import ( - "os" - "template" - "io/ioutil" -) - -func main() { - b, _ := ioutil.ReadAll(os.Stdin) - template.HTMLFormatter(os.Stdout, "", b) -} diff --git a/doc/codelab/wiki/http-sample.go b/doc/codelab/wiki/http-sample.go deleted file mode 100644 index 33379a1b6..000000000 --- a/doc/codelab/wiki/http-sample.go +++ /dev/null @@ -1,15 +0,0 @@ -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 deleted file mode 100644 index cc187ad90..000000000 --- a/doc/codelab/wiki/index.html +++ /dev/null @@ -1,1003 +0,0 @@ -<!-- 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. 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}</h1> - -<form action="/save/{Title}" method="POST"> -<div><textarea name="body" rows="20" cols="80">{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", nil) - 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> replaces all occurrences of -<code>{Title}</code> and <code>{Body}</code> with the values of -<code>p.Title</code> and <code>p.Body</code>, and writes the resultant -HTML to the <code>http.ResponseWriter</code>. -</p> - -<p> -Note that we've used <code>{Body|html}</code> in the above template. -The <code>|html</code> part asks the template engine to pass the value -<code>Body</code> through the <code>html</code> formatter before outputting it, -which escapes HTML characters (such as replacing <code>></code> with -<code>&gt;</code>). -This will prevent 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}</h1> - -<p>[<a href="/edit/{Title}">edit</a>]</p> - -<div>{Body}</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", nil) - 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.MustParseFile</code> is a convenience wrapper around -<code>ParseFile</code> that does not return an error code; instead, it panics -if an error is encountered. 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"} { - templates[tmpl] = template.MustParseFile(tmpl+".html", nil) - } -} -</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>, like <code>template.MustParseFile</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 deleted file mode 100644 index 9cbe9ad76..000000000 --- a/doc/codelab/wiki/notemplate.go +++ /dev/null @@ -1,55 +0,0 @@ -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 deleted file mode 100644 index 14cfc321a..000000000 --- a/doc/codelab/wiki/part1-noerror.go +++ /dev/null @@ -1,30 +0,0 @@ -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 deleted file mode 100644 index 4b0654f8b..000000000 --- a/doc/codelab/wiki/part1.go +++ /dev/null @@ -1,33 +0,0 @@ -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 deleted file mode 100644 index d57c3a01f..000000000 --- a/doc/codelab/wiki/part2.go +++ /dev/null @@ -1,40 +0,0 @@ -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 deleted file mode 100644 index 67294784e..000000000 --- a/doc/codelab/wiki/srcextract.go +++ /dev/null @@ -1,72 +0,0 @@ -package main - -import ( - "bytes" - "flag" - "go/parser" - "go/printer" - "go/ast" - "go/token" - "log" - "os" - "template" -) - -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 deleted file mode 100755 index ed63ff20f..000000000 --- a/doc/codelab/wiki/test.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/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 deleted file mode 100644 index f0eec86f6..000000000 --- a/doc/codelab/wiki/test_Test.txt.good +++ /dev/null @@ -1 +0,0 @@ -some content
\ No newline at end of file diff --git a/doc/codelab/wiki/test_edit.good b/doc/codelab/wiki/test_edit.good deleted file mode 100644 index 36c6dbb73..000000000 --- a/doc/codelab/wiki/test_edit.good +++ /dev/null @@ -1,6 +0,0 @@ -<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 deleted file mode 100644 index 07e8edb22..000000000 --- a/doc/codelab/wiki/test_view.good +++ /dev/null @@ -1,5 +0,0 @@ -<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 deleted file mode 100644 index ca2ffc20b..000000000 --- a/doc/codelab/wiki/view.html +++ /dev/null @@ -1,5 +0,0 @@ -<h1>{Title}</h1> - -<p>[<a href="/edit/{Title}">edit</a>]</p> - -<div>{Body}</div> diff --git a/doc/codelab/wiki/wiki.html b/doc/codelab/wiki/wiki.html deleted file mode 100644 index 4db880b9d..000000000 --- a/doc/codelab/wiki/wiki.html +++ /dev/null @@ -1,781 +0,0 @@ -<!-- 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. 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> replaces all occurrences of -<code>{Title}</code> and <code>{Body}</code> with the values of -<code>p.Title</code> and <code>p.Body</code>, and writes the resultant -HTML to the <code>http.ResponseWriter</code>. -</p> - -<p> -Note that we've used <code>{Body|html}</code> in the above template. -The <code>|html</code> part asks the template engine to pass the value -<code>Body</code> through the <code>html</code> formatter before outputting it, -which escapes HTML characters (such as replacing <code>></code> with -<code>&gt;</code>). -This will prevent 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.MustParseFile</code> is a convenience wrapper around -<code>ParseFile</code> that does not return an error code; instead, it panics -if an error is encountered. 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>, like <code>template.MustParseFile</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 deleted file mode 100644 index 33f415f13..000000000 --- a/doc/codereview_with_mq.html +++ /dev/null @@ -1,113 +0,0 @@ -<!-- 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 deleted file mode 100644 index a0814e4d2..000000000 --- a/doc/codewalk/codewalk.css +++ /dev/null @@ -1,234 +0,0 @@ -/* - 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 deleted file mode 100644 index f780bc7a5..000000000 --- a/doc/codewalk/codewalk.js +++ /dev/null @@ -1,305 +0,0 @@ -// 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 deleted file mode 100644 index 9cd8361e8..000000000 --- a/doc/codewalk/codewalk.xml +++ /dev/null @@ -1,124 +0,0 @@ -<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 deleted file mode 100644 index 986a017e1..000000000 --- a/doc/codewalk/functions.xml +++ /dev/null @@ -1,115 +0,0 @@ -<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/pig.go b/doc/codewalk/pig.go deleted file mode 100644 index 9e415f589..000000000 --- a/doc/codewalk/pig.go +++ /dev/null @@ -1,124 +0,0 @@ -// 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 differdeleted file mode 100644 index 9c0c23638..000000000 --- a/doc/codewalk/popout.png +++ /dev/null diff --git a/doc/codewalk/sharemem.xml b/doc/codewalk/sharemem.xml deleted file mode 100644 index 1a669f7b5..000000000 --- a/doc/codewalk/sharemem.xml +++ /dev/null @@ -1,181 +0,0 @@ -<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 deleted file mode 100644 index b51be9502..000000000 --- a/doc/codewalk/urlpoll.go +++ /dev/null @@ -1,117 +0,0 @@ -// 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 deleted file mode 100644 index c3b16cacb..000000000 --- a/doc/community.html +++ /dev/null @@ -1,53 +0,0 @@ -<!-- 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 deleted file mode 100644 index 84d2cda6a..000000000 --- a/doc/contrib.html +++ /dev/null @@ -1,69 +0,0 @@ -<!-- 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 deleted file mode 100644 index c4b1ce2b5..000000000 --- a/doc/contribute.html +++ /dev/null @@ -1,529 +0,0 @@ -<!-- 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 deleted file mode 100644 index ae405bf52..000000000 --- a/doc/devel/index.html +++ /dev/null @@ -1,11 +0,0 @@ -<!-- 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 deleted file mode 100644 index feb433f14..000000000 --- a/doc/devel/release.html +++ /dev/null @@ -1,361 +0,0 @@ -<!-- 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="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.tool">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 deleted file mode 100644 index d3c494715..000000000 --- a/doc/devel/roadmap.html +++ /dev/null @@ -1,135 +0,0 @@ -<!-- 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 deleted file mode 100644 index 0fb6483f4..000000000 --- a/doc/devel/weekly.html +++ /dev/null @@ -1,3497 +0,0 @@ -<!-- 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-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 deleted file mode 100644 index 9fd3dcebe..000000000 --- a/doc/docs.html +++ /dev/null @@ -1,236 +0,0 @@ -<!-- 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 deleted file mode 100644 index 2ecef44f4..000000000 --- a/doc/effective_go.html +++ /dev/null @@ -1,3038 +0,0 @@ -<!-- 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 require 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, add 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: -parentheses are not required -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 for you. -</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 essentially the same as its namesakes -in other languages: <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 intitial 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" - "template" -) - -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 deleted file mode 100644 index 299855ce9..000000000 --- a/doc/frontpage.css +++ /dev/null @@ -1,143 +0,0 @@ -/* 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 deleted file mode 100644 index 8eeb3a5c5..000000000 --- a/doc/gccgo_contribute.html +++ /dev/null @@ -1,99 +0,0 @@ -<!-- 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 deleted file mode 100644 index 159fab7bb..000000000 --- a/doc/gccgo_install.html +++ /dev/null @@ -1,409 +0,0 @@ -<!-- 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 differdeleted file mode 100644 index 29be31943..000000000 --- a/doc/go-logo-black.png +++ /dev/null diff --git a/doc/go-logo-blue.png b/doc/go-logo-blue.png Binary files differdeleted file mode 100644 index b9eac2727..000000000 --- a/doc/go-logo-blue.png +++ /dev/null diff --git a/doc/go-logo-white.png b/doc/go-logo-white.png Binary files differdeleted file mode 100644 index 4011069eb..000000000 --- a/doc/go-logo-white.png +++ /dev/null diff --git a/doc/go_faq.html b/doc/go_faq.html deleted file mode 100644 index 560ab3617..000000000 --- a/doc/go_faq.html +++ /dev/null @@ -1,1254 +0,0 @@ -<!-- 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: - -<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> - -<p> -We believe it's worth trying again with a new language, a concurrent, -garbage-collected language with fast compilation. Regarding the points above: - -<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> -</p> - -<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> -Many others 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. Instead of exceptions, it 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 even 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, really—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. -</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—having one or even zero methods -in an interface can express useful concepts. -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 exciting 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="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> - -<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) someMethod() { } // method on pointer -func (s MyStruct) someMethod() { } // method on value -</pre> - -<p> -When defining a method on a type, the receiver (<code>s</code> in the above -example) behaves exactly is if it were an argument to the method. Define the -method on a pointer type if you need the method to modify the data the receiver -points to. Otherwise, it is often cleaner to define the method on a value type. -</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> - -<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> - -<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 <a href="http://blog.golang.org/2010/07/gos-declaration-syntax.html">Go's Declaration Syntax</a> article 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> diff --git a/doc/go_for_cpp_programmers.html b/doc/go_for_cpp_programmers.html deleted file mode 100644 index 7168f1d05..000000000 --- a/doc/go_for_cpp_programmers.html +++ /dev/null @@ -1,707 +0,0 @@ -<!-- 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 deleted file mode 100644 index a38828358..000000000 --- a/doc/go_mem.html +++ /dev/null @@ -1,510 +0,0 @@ -<!-- 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 deleted file mode 100644 index 489ad4db3..000000000 --- a/doc/go_spec.html +++ /dev/null @@ -1,5272 +0,0 @@ -<!-- title The Go Programming Language Specification --> -<!-- subtitle Version of June 17, 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" Statement ] . -</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 deleted file mode 100644 index 822f9626e..000000000 --- a/doc/go_tutorial.html +++ /dev/null @@ -1,1455 +0,0 @@ -<!-- 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> -Program snippets are annotated with the line number in the original file; for -cleanliness, blank lines remain blank. -<p> -<h2>Hello, World</h2> -<p> -Let's start in the usual way: -<p> -<pre><!-- 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><!-- 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> -Having imported the <code>flag</code> package, line 12 creates a global variable to hold -the value of echo's <code>-n</code> flag. The variable <code>omitNewline</code> has type <code>*bool</code>, pointer -to <code>bool</code>. -<p> -In <code>main.main</code>, we parse the arguments (line 20) and then create a local -string variable we will use 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><!-- 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><!-- 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><!-- 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><!-- 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><!-- 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 on line 21. -<p> -We can use the factory to construct some familiar, exported variables of type <code>*File</code>: -<p> -<pre><!-- 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><!-- 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 line 31; 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, line 35 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><!-- 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><!-- 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><!-- 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><!-- 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><!-- 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><!-- 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><!-- 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><!-- 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><!-- 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><!-- 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><!-- 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><!-- 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><!-- 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><!-- 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><!-- 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><!-- 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><!-- 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><!-- 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><!-- 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><!-- 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><!-- 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><!-- 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><!-- 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><!-- 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><!-- 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><!-- 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><!-- 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><!-- 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><!-- 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><!-- 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><!-- 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><!-- 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><!-- progs/server1.go /adder,.quit/ ---> adder, quit := startServer(func(a, b int) int { return a + b }) -</pre> -... -<pre><!-- 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.txt b/doc/go_tutorial.txt deleted file mode 100644 index 17ef6eee9..000000000 --- a/doc/go_tutorial.txt +++ /dev/null @@ -1,934 +0,0 @@ -<!-- A Tutorial for the Go Programming Language --> -Introduction ----- - -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>. - -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'>"/doc/progs/"</a>. - -Program snippets are annotated with the line number in the original file; for -cleanliness, blank lines remain blank. - -Hello, World ----- - -Let's start in the usual way: - -!src progs/helloworld.go /package/ $ - -Every Go source file declares, using a "package" statement, which package it's part of. -It may also import other packages to use their facilities. -This program imports the package "fmt" to gain access to -our old, now capitalized and package-qualified, friend, "fmt.Printf". - -Functions are introduced with the "func" keyword. -The "main" package's "main" function is where the program starts running (after -any initialization). - -String constants can contain Unicode characters, encoded in UTF-8. -(In fact, Go source files are defined to be encoded in UTF-8.) - -The comment convention is the same as in C++: - - /* ... */ - // ... - -Later we'll have much more to say about printing. - -Semicolons ----- - -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 "for" loops and the like; they are not necessary after -every statement. - -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. - -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. - -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 "if" statement on the same line as -the "if"; 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. - -Compiling ----- - -Go is a compiled language. At the moment there are two compilers. -"Gccgo" 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: -"6g" for the 64-bit x86, "8g" for the 32-bit x86, and more. These -compilers run significantly faster but generate less efficient code -than "gccgo". At the time of writing (late 2009), they also have -a more robust run-time system although "gccgo" is catching up. - -Here's how to compile and run our program. With "6g", say, - - $ 6g helloworld.go # compile; object goes into helloworld.6 - $ 6l helloworld.6 # link; output goes into 6.out - $ 6.out - Hello, world; or Καλημέρα κόσμε; or こんにちは 世界 - $ - -With "gccgo" it looks a little more traditional. - - $ gccgo helloworld.go - $ a.out - Hello, world; or Καλημέρα κόσμε; or こんにちは 世界 - $ - -Echo ----- - -Next up, here's a version of the Unix utility "echo(1)": - -!src progs/echo.go /package/ $ - -This program is small but it's doing a number of new things. In the last example, -we saw "func" introduce a function. The keywords "var", "const", and "type" -(not used yet) also introduce declarations, as does "import". -Notice that we can group declarations of the same sort into -parenthesized lists, one item per line, as in the "import" and "const" clauses here. -But it's not necessary to do so; we could have said - - const Space = " " - const Newline = "\n" - -This program imports the ""os"" package to access its "Stdout" variable, of type -"*os.File". The "import" statement is actually a declaration: in its general form, -as used in our ``hello world'' program, -it names the identifier ("fmt") -that will be used to access members of the package imported from the file (""fmt""), -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 "import "fmt"". - -You can specify your -own import names if you want but it's only necessary if you need to resolve -a naming conflict. - -Given "os.Stdout" we can use its "WriteString" method to print the string. - -Having imported the "flag" package, line 12 creates a global variable to hold -the value of echo's "-n" flag. The variable "omitNewline" has type "*bool", pointer -to "bool". - -In "main.main", we parse the arguments (line 20) and then create a local -string variable we will use to build the output. - -The declaration statement has the form - - var s string = "" - -This is the "var" keyword, followed by the name of the variable, followed by -its type, followed by an equals sign and an initial value for the variable. - -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 - - var s = "" - -or we could go even shorter and write the idiom - - s := "" - -The ":=" operator is used a lot in Go to represent an initializing declaration. -There's one in the "for" clause on the next line: - -!src progs/echo.go /for/ - -The "flag" package has parsed the arguments and left the non-flag arguments -in a list that can be iterated over in the obvious way. - -The Go "for" statement differs from that of C in a number of ways. First, -it's the only looping construct; there is no "while" or "do". Second, -there are no parentheses on the clause, but the braces on the body -are mandatory. The same applies to the "if" and "switch" statements. -Later examples will show some other ways "for" can be written. - -The body of the loop builds up the string "s" by appending (using "+=") -the arguments and separating spaces. After the loop, if the "-n" flag is not -set, the program appends a newline. Finally, it writes the result. - -Notice that "main.main" is a niladic function with no return type. -It's defined that way. Falling off the end of "main.main" means -''success''; if you want to signal an erroneous return, call - - os.Exit(1) - -The "os" package contains other essentials for getting -started; for instance, "os.Args" is a slice used by the -"flag" package to access the command-line arguments. - -An Interlude about Types ----- - -Go has some familiar types such as "int" and "uint" (unsigned "int"), which represent -values of the ''appropriate'' size for the machine. It also defines -explicitly-sized types such as "int8", "float64", and so on, plus -unsigned integer types such as "uint", "uint32", etc. -These are distinct types; even if "int" and "int32" are both 32 bits in size, -they are not the same type. There is also a "byte" synonym for -"uint8", which is the element type for strings. - -Floating-point types are always sized: "float32" and "float64", -plus "complex64" (two "float32s") and "complex128" -(two "float64s"). Complex numbers are outside the -scope of this tutorial. - -Speaking of "string", that's a built-in type as well. Strings are -<i>immutable values</i>—they are not just arrays of "byte" 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 "strings.go" is legal code: - -!src progs/strings.go /hello/ /ciao/ - -However the following statements are illegal because they would modify -a "string" value: - - s[0] = 'x' - (*p)[1] = 'y' - -In C++ terms, Go strings are a bit like "const strings", while pointers -to strings are analogous to "const string" references. - -Yes, there are pointers. However, Go simplifies their use a little; -read on. - -Arrays are declared like this: - - var arrayOfInt [10]int - -Arrays, like strings, are values, but they are mutable. This differs -from C, in which "arrayOfInt" would be usable as a pointer to "int". -In Go, since arrays are values, it's meaningful (and useful) to talk -about pointers to arrays. - -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 "a[low : high]", representing -the internal array indexed from "low" through "high-1"; the resulting -slice is indexed from "0" through "high-low-1". -In short, slices look a lot like arrays but with -no explicit size ("[]" vs. "[10]") 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. - -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: - - [3]int{1,2,3} - -In this case the constructor builds an array of 3 "ints". - -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 "[:]" -will slice the whole array. - -Using slices one can write this function (from "sum.go"): - -!src progs/sum.go /sum/ /^}/ - -Note how the return type ("int") is defined for "sum" by stating it -after the parameter list. - -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: - - s := sum([3]int{1,2,3}[:]) - -If you are creating a regular array but want the compiler to count the -elements for you, use "..." as the array size: - - s := sum([...]int{1,2,3}[:]) - -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: - - s := sum([]int{1,2,3}) - -There are also maps, which you can initialize like this: - - m := map[string]int{"one":1 , "two":2} - -The built-in function "len", which returns number of elements, -makes its first appearance in "sum". It works on strings, arrays, -slices, maps, and channels. - -By the way, another thing that works on strings, arrays, slices, maps -and channels is the "range" clause on "for" loops. Instead of writing - - for i := 0; i < len(a); i++ { ... } - -to loop over the elements of a slice (or map or ...) , we could write - - for i, v := range a { ... } - -This assigns "i" to the index and "v" 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. - - -An Interlude about Allocation ----- - -Most types in Go are values. If you have an "int" or a "struct" -or an array, assignment -copies the contents of the object. -To allocate a new variable, use the built-in function "new", which -returns a pointer to the allocated storage. - - type T struct { a, b int } - var t *T = new(T) - -or the more idiomatic - - t := new(T) - -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 "make": - - m := make(map[string]int) - -This statement initializes a new map ready to store entries. -If you just declare the map, as in - - var m map[string]int - -it creates a "nil" reference that cannot hold anything. To use the map, -you must first initialize the reference using "make" or by assignment from an -existing map. - -Note that "new(T)" returns type "*T" while "make(T)" returns type -"T". If you (mistakenly) allocate a reference object with "new" rather than "make", -you receive a pointer to a nil reference, equivalent to -declaring an uninitialized variable and taking its address. - -An Interlude about Constants ----- - -Although integers come in lots of sizes in Go, integer constants do not. -There are no constants like "0LL" or "0x0UL". 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. - - const hardEight = (1 << 100) >> 97 // legal - -There are nuances that deserve redirection to the legalese of the -language specification but here are some illustrative examples: - - 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 - -Conversions only work for simple cases such as converting "ints" 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. - -An I/O Package ----- - -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 "file.go": - -!src progs/file.go /package/ /^}/ - -The first few lines declare the name of the -package—"file"—and then import two packages. The "os" -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. - -The other item is the low-level, external "syscall" package, which provides -a primitive interface to the underlying operating system's calls. - -Next is a type definition: the "type" keyword introduces a type declaration, -in this case a data structure called "File". -To make things a little more interesting, our "File" includes the name of the file -that the file descriptor refers to. - -Because "File" 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''. - -In the case of "File", all its fields are lower case and so invisible to users, but we -will soon give it some exported, upper-case methods. - -First, though, here is a factory to create a "File": - -!src progs/file.go /newFile/ /^}/ - -This returns a pointer to a new "File" 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 - - n := new(File) - n.fd = fd - n.name = name - return n - -but for simple structures like "File" it's easier to return the address of a -composite literal, as is done here on line 21. - -We can use the factory to construct some familiar, exported variables of type "*File": - -!src progs/file.go /var/ /^.$/ - -The "newFile" function was not exported because it's internal. The proper, -exported factory to use is "OpenFile" (we'll explain that name in a moment): - -!src progs/file.go /func.OpenFile/ /^}/ - -There are a number of new things in these few lines. First, "OpenFile" returns -multiple values, a "File" 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 -"syscall.Open" -also has a multi-value return, which we can grab with the multi-variable -declaration on line 31; it declares "r" and "e" to hold the two values, -both of type "int" (although you'd have to look at the "syscall" package -to see that). Finally, line 35 returns two values: a pointer to the new "File" -and the error. If "syscall.Open" fails, the file descriptor "r" will -be negative and "newFile" will return "nil". - -About those errors: The "os" 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 "Open" we use a -conversion to translate Unix's integer "errno" value into the integer type -"os.Errno", which implements "os.Error". - -Why "OpenFile" and not "Open"? To mimic Go's "os" package, which -our exercise is emulating. The "os" package takes the opportunity -to make the two commonest cases - open for read and create for -write - the simplest, just "Open" and "Create". "OpenFile" is the -general case, analogous to the Unix system call "Open". Here is -the implementation of our "Open" and "Create"; they're trivial -wrappers that eliminate common errors by capturing -the tricky standard arguments to open and, especially, to create a file: - -!src progs/file.go /^const/ /^}/ - -!src progs/file.go /func.Create/ /^}/ - -Back to our main story. -Now that we can build "Files", 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 "*File", -each of which declares a receiver variable "file". - -!src progs/file.go /Close/ $ - -There is no implicit "this" and the receiver variable must be used to access -members of the structure. Methods are not declared within -the "struct" declaration itself. The "struct" 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 "structs". We'll see an example with arrays later. - -The "String" method is so called because of a printing convention we'll -describe later. - -The methods use the public variable "os.EINVAL" to return the ("os.Error" -version of the) Unix error code "EINVAL". The "os" library defines a standard -set of such error values. - -We can now use our new package: - -!src progs/helloworld3.go /package/ $ - -The ''"./"'' in the import of ''"./file"'' tells the compiler -to use our own package rather than -something from the directory of installed packages. -(Also, ''"file.go"'' must be compiled before we can import the -package.) - -Now we can compile and run the program. On Unix, this would be the result: - - $ 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 - $ - -Rotting cats ----- - -Building on the "file" package, here's a simple version of the Unix utility "cat(1)", -"progs/cat.go": - -!src progs/cat.go /package/ $ - -By now this should be easy to follow, but the "switch" statement introduces some -new features. Like a "for" loop, an "if" or "switch" can include an -initialization statement. The "switch" statement in "cat" uses one to create variables -"nr" and "er" to hold the return values from the call to "f.Read". (The "if" a few lines later -has the same idea.) The "switch" 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. - -Since the "switch" value is just "true", we could leave it off—as is also -the situation -in a "for" statement, a missing value means "true". In fact, such a "switch" -is a form of "if-else" chain. While we're here, it should be mentioned that in -"switch" statements each "case" has an implicit "break". - -The argument to "file.Stdout.Write" is created by slicing the array "buf". -Slices provide the standard Go way to handle I/O buffers. - -Now let's make a variant of "cat" that optionally does "rot13" 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>. - -The "cat" subroutine uses only two methods of "f": "Read" and "String", -so let's start by defining an interface that has exactly those two methods. -Here is code from "progs/cat_rot13.go": - -!src progs/cat_rot13.go /type.reader/ /^}/ - -Any type that has the two methods of "reader"—regardless of whatever -other methods the type may also have—is said to <i>implement</i> the -interface. Since "file.File" implements these methods, it implements the -"reader" interface. We could tweak the "cat" subroutine to accept a "reader" -instead of a "*file.File" and it would work just fine, but let's embellish a little -first by writing a second type that implements "reader", one that wraps an -existing "reader" and does "rot13" 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 "reader" interface. - -!src progs/cat_rot13.go /type.rotate13/ /end.of.rotate13/ - -(The "rot13" function called in "Read" is trivial and not worth reproducing here.) - -To use the new feature, we define a flag: - -!src progs/cat_rot13.go /rot13Flag/ - -and use it from within a mostly unchanged "cat" function: - -!src progs/cat_rot13.go /func.cat/ /^}/ - -(We could also do the wrapping in "main" and leave "cat" mostly alone, except -for changing the type of the argument; consider that an exercise.) -The "if" at the top of "cat" sets it all up: If the "rot13" flag is true, wrap the "reader" -we received into a "rotate13" and proceed. Note that the interface variables -are values, not pointers: the argument is of type "reader", not "*reader", -even though under the covers it holds a pointer to a "struct". - -Here it is in action: - - $ echo abcdefghijklmnopqrstuvwxyz | ./cat - abcdefghijklmnopqrstuvwxyz - $ echo abcdefghijklmnopqrstuvwxyz | ./cat --rot13 - nopqrstuvwxyzabcdefghijklm - $ - -Fans of dependency injection may take cheer from how easily interfaces -allow us to substitute the implementation of a file descriptor. - -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 "rot13". The type "file.File" implements "reader"; it could also -implement a "writer", or any other interface built from its methods that -fits the current situation. Consider the <i>empty interface</i> - - type Empty interface {} - -<i>Every</i> type implements the empty interface, which makes it -useful for things like containers. - -Sorting ----- - -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. - -As an example, consider this simple sort algorithm taken from "progs/sort.go": - -!src progs/sort.go /func.Sort/ /^}/ - -The code needs only three methods, which we wrap into sort's "Interface": - -!src progs/sort.go /interface/ /^}/ - -We can apply "Sort" to any type that implements "Len", "Less", and "Swap". -The "sort" package includes the necessary methods to allow sorting of -arrays of integers, strings, etc.; here's the code for arrays of "int" - -!src progs/sort.go /type.*IntSlice/ /Swap/ - -Here we see methods defined for non-"struct" types. You can define methods -for any type you define and name in your package. - -And now a routine to test it out, from "progs/sortmain.go". This -uses a function in the "sort" package, omitted here for brevity, -to test that the result is sorted. - -!src progs/sortmain.go /func.ints/ /^}/ - -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: - -!src progs/sortmain.go /type.day/ /Swap/ - - -Printing ----- - -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. - -We've seen simple uses of the package "fmt", which -implements "Printf", "Fprintf", and so on. -Within the "fmt" package, "Printf" is declared with this signature: - - Printf(format string, v ...interface{}) (n int, errno os.Error) - -The token "..." introduces a variable-length argument list that in C would -be handled using the "stdarg.h" macros. -In Go, variadic functions are passed a slice of the arguments of the -specified type. In "Printf"'s case, the declaration says "...interface{}" -so the actual type is a slice of empty interface values, "[]interface{}". -"Printf" 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 "Printf", -due to the ability of "Printf" to discover the type of its arguments -dynamically. - -For example, in C each format must correspond to the type of its -argument. It's easier in many cases in Go. Instead of "%llud" you -can just say "%d"; "Printf" knows the size and signedness of the -integer and can do the right thing for you. The snippet - -!src progs/print.go 10 11 - -prints - - 18446744073709551615 -1 - -In fact, if you're lazy the format "%v" will print, in a simple -appropriate style, any value, even an array or structure. The output of - -!src progs/print.go 14 20 - -is - - 18446744073709551615 {77 Sunset Strip} [1 2 3 4] - -You can drop the formatting altogether if you use "Print" or "Println" -instead of "Printf". Those routines do fully automatic formatting. -The "Print" function just prints its elements out using the equivalent -of "%v" while "Println" inserts spaces between arguments -and adds a newline. The output of each of these two lines is identical -to that of the "Printf" call above. - -!src progs/print.go 21 22 - -If you have your own type you'd like "Printf" or "Print" to format, -just give it a "String" 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. - -!src progs/print_string.go 9 $ - -Since "*testType" has a "String" method, the -default formatter for that type will use it and produce the output - - 77 Sunset Strip - -Observe that the "String" method calls "Sprint" (the obvious Go -variant that returns a string) to do its formatting; special formatters -can use the "fmt" library recursively. - -Another feature of "Printf" is that the format "%T" will print a string -representation of the type of a value, which can be handy when debugging -polymorphic code. - -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. - -You might ask, though, how "Printf" can tell whether a type implements -the "String" 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 "v", it does this: - - - type Stringer interface { - String() string - } - - s, ok := v.(Stringer) // Test whether v implements "String()" - if ok { - result = s.String() - } else { - result = defaultOutput(v) - } - -The code uses a ``type assertion'' ("v.(Stringer)") to test if the value stored in -"v" satisfies the "Stringer" interface; if it does, "s" -will become an interface variable implementing the method and "ok" will -be "true". 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, "ok" will be false. - -In this snippet the name "Stringer" follows the convention that we add ''[e]r'' -to interfaces describing simple method sets like this. - -One last wrinkle. To complete the suite, besides "Printf" etc. and "Sprintf" -etc., there are also "Fprintf" etc. Unlike in C, "Fprintf"'s first argument is -not a file. Instead, it is a variable of type "io.Writer", which is an -interface type defined in the "io" library: - - type Writer interface { - Write(p []byte) (n int, err os.Error) - } - -(This interface is another conventional name, this time for "Write"; there are also -"io.Reader", "io.ReadWriter", and so on.) -Thus you can call "Fprintf" on any type that implements a standard "Write" -method, not just files but also network channels, buffers, whatever -you want. - -Prime numbers ----- - -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. - -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. - -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. - -<br> - - <img src='sieve.gif'> - -<br> - -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 -"make" to create a new channel. - -Here is the first function in "progs/sieve.go": - -!src progs/sieve.go /Send/ /^}/ - -The "generate" function sends the sequence 2, 3, 4, 5, ... to its -argument channel, "ch", using the binary communications operator "<-". -Channel operations block, so if there's no recipient for the value on "ch", -the send operation will wait until one becomes available. - -The "filter" 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 "<-" (receive) retrieves the next value on the channel. - -!src progs/sieve.go /Copy.the/ /^}/ - -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 "go"; -this starts the function running in parallel with the current -computation but in the same address space: - - go sum(hugeArray) // calculate sum in the background - -If you want to know when the calculation is done, pass a channel -on which it can report back: - - ch := make(chan int) - go sum(hugeArray, ch) - // ... do something else for a while - result := <-ch // wait for, and retrieve, result - -Back to our prime sieve. Here's how the sieve pipeline is stitched -together: - -!src progs/sieve.go /func.main/ /^}/ - -The first line of "main" creates the initial channel to pass to "generate", which it -then starts up. As each prime pops out of the channel, a new "filter" -is added to the pipeline and <i>its</i> output becomes the new value -of "ch". - -The sieve program can be tweaked to use a pattern common -in this style of programming. Here is a variant version -of "generate", from "progs/sieve1.go": - -!src progs/sieve1.go /func.generate/ /^}/ - -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. - -The function literal notation used in the "go" statement allows us to construct an -anonymous function and invoke it on the spot. Notice that the local -variable "ch" is available to the function literal and lives on even -after "generate" returns. - -The same change can be made to "filter": - -!src progs/sieve1.go /func.filter/ /^}/ - -The "sieve" 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: - -!src progs/sieve1.go /func.sieve/ /^}/ - -Now "main"'s interface to the prime sieve is a channel of primes: - -!src progs/sieve1.go /func.main/ /^}/ - -Multiplexing ----- - -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 "request" type, which embeds a channel -that will be used for the reply. - -!src progs/server.go /type.request/ /^}/ - -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: - -!src progs/server.go /type.binOp/ /^}/ - -The type declaration makes "binOp" represent a function taking two integers and -returning a third. - -The "server" routine loops forever, receiving requests and, to avoid blocking due to -a long-running operation, starting a goroutine to do the actual work. - -!src progs/server.go /func.server/ /^}/ - -We construct a server in a familiar way, starting it and returning a channel -connected to it: - -!src progs/server.go /func.startServer/ /^}/ - -Here's a simple test. It starts a server with an addition operator and sends out -"N" requests without waiting for the replies. Only after all the requests are sent -does it check the results. - -!src progs/server.go /func.main/ /^}/ - -One annoyance with this program is that it doesn't shut down the server cleanly; when "main" returns -there are a number of lingering goroutines blocked on communication. To solve this, -we can provide a second, "quit" channel to the server: - -!src progs/server1.go /func.startServer/ /^}/ - -It passes the quit channel to the "server" function, which uses it like this: - -!src progs/server1.go /func.server/ /^}/ - -Inside "server", the "select" 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 "select" allows -the server to honor requests until it receives a quit message, at which point it -returns, terminating its execution. - - -All that's left is to strobe the "quit" channel -at the end of main: - -!src progs/server1.go /adder,.quit/ -... -!src progs/server1.go /quit....true/ - -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 deleted file mode 100644 index 946c4c39f..000000000 --- a/doc/godocs.js +++ /dev/null @@ -1,190 +0,0 @@ -// 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 differdeleted file mode 100644 index 0a6430666..000000000 --- a/doc/gopher/appenginegopher.jpg +++ /dev/null diff --git a/doc/gopher/appenginegophercolor.jpg b/doc/gopher/appenginegophercolor.jpg Binary files differdeleted file mode 100644 index 68795a99b..000000000 --- a/doc/gopher/appenginegophercolor.jpg +++ /dev/null diff --git a/doc/gopher/appenginelogo.gif b/doc/gopher/appenginelogo.gif Binary files differdeleted file mode 100644 index 46b3c1eeb..000000000 --- a/doc/gopher/appenginelogo.gif +++ /dev/null diff --git a/doc/gopher/bumper.png b/doc/gopher/bumper.png Binary files differdeleted file mode 100644 index 6b41c1fd0..000000000 --- a/doc/gopher/bumper.png +++ /dev/null diff --git a/doc/gopher/bumper192x108.png b/doc/gopher/bumper192x108.png Binary files differdeleted file mode 100644 index 470a74df5..000000000 --- a/doc/gopher/bumper192x108.png +++ /dev/null diff --git a/doc/gopher/bumper320x180.png b/doc/gopher/bumper320x180.png Binary files differdeleted file mode 100644 index 5b31b5d31..000000000 --- a/doc/gopher/bumper320x180.png +++ /dev/null diff --git a/doc/gopher/bumper480x270.png b/doc/gopher/bumper480x270.png Binary files differdeleted file mode 100644 index 621f51b65..000000000 --- a/doc/gopher/bumper480x270.png +++ /dev/null diff --git a/doc/gopher/bumper640x360.png b/doc/gopher/bumper640x360.png Binary files differdeleted file mode 100644 index 9c898d0c7..000000000 --- a/doc/gopher/bumper640x360.png +++ /dev/null diff --git a/doc/gopher/gopherbw.png b/doc/gopher/gopherbw.png Binary files differdeleted file mode 100644 index 48a08cc61..000000000 --- a/doc/gopher/gopherbw.png +++ /dev/null diff --git a/doc/gopher/gophercolor.png b/doc/gopher/gophercolor.png Binary files differdeleted file mode 100644 index b48ffba37..000000000 --- a/doc/gopher/gophercolor.png +++ /dev/null diff --git a/doc/gopher/gophercolor16x16.png b/doc/gopher/gophercolor16x16.png Binary files differdeleted file mode 100644 index 48854ff3b..000000000 --- a/doc/gopher/gophercolor16x16.png +++ /dev/null diff --git a/doc/htmlgen.go b/doc/htmlgen.go deleted file mode 100644 index 5318a07dc..000000000 --- a/doc/htmlgen.go +++ /dev/null @@ -1,312 +0,0 @@ -// 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. - -// If --html is set, process plain text into HTML. -// - h2's are made from lines followed by a line "----\n" -// - tab-indented blocks become <pre> blocks with the first tab deleted -// - blank lines become <p> marks (except inside <pre> tags) -// - "quoted strings" become <code>quoted strings</code> - -// Lines beginning !src define pieces of program source to be -// extracted from other files and injected as <pre> blocks. -// The syntax is simple: 1, 2, or 3 space-separated arguments: -// -// Whole file: -// !src foo.go -// One line (here the signature of main): -// !src foo.go /^func.main/ -// Block of text, determined by start and end (here the body of main): -// !src foo.go /^func.main/ /^}/ -// -// Patterns can be /regular.expression/, a decimal number, or $ -// to signify the end of the file. -// TODO: the regular expression cannot contain spaces; does this matter? - -package main - -import ( - "bufio" - "bytes" - "flag" - "fmt" - "io/ioutil" - "log" - "os" - "regexp" - "strconv" - "strings" - "template" -) - -var ( - html = flag.Bool("html", true, "process text into HTML") -) - -var ( - // lines holds the input and is reworked in place during processing. - lines = make([][]byte, 0, 20000) - - empty = []byte("") - newline = []byte("\n") - tab = []byte("\t") - quote = []byte(`"`) - indent = []byte(" ") - - sectionMarker = []byte("----\n") - preStart = []byte("<pre>") - preEnd = []byte("</pre>\n") - pp = []byte("<p>\n") - - srcPrefix = []byte("!src") -) - -func main() { - flag.Parse() - read() - programs() - if *html { - headings() - coalesce(preStart, foldPre) - coalesce(tab, foldTabs) - paragraphs() - quotes() - } - write() -} - -// read turns standard input into a slice of lines. -func read() { - b := bufio.NewReader(os.Stdin) - for { - line, err := b.ReadBytes('\n') - if err == os.EOF { - break - } - if err != nil { - log.Fatal(err) - } - lines = append(lines, line) - } -} - -// write puts the result on standard output. -func write() { - b := bufio.NewWriter(os.Stdout) - for _, line := range lines { - b.Write(expandTabs(line)) - } - b.Flush() -} - -// programs injects source code from !src invocations. -func programs() { - nlines := make([][]byte, 0, len(lines)*3/2) - for _, line := range lines { - if bytes.HasPrefix(line, srcPrefix) { - line = trim(line)[len(srcPrefix):] - prog := srcCommand(string(line)) - if *html { - nlines = append(nlines, []byte(fmt.Sprintf("<pre><!--%s\n-->", line))) - } - for _, l := range prog { - nlines = append(nlines, htmlEscape(l)) - } - if *html { - nlines = append(nlines, preEnd) - } - } else { - nlines = append(nlines, line) - } - } - lines = nlines -} - -// srcCommand processes one !src invocation. -func srcCommand(command string) [][]byte { - // TODO: quoted args so we can have 'a b'? - args := strings.Fields(command) - if len(args) == 0 || len(args) > 3 { - log.Fatal("bad syntax for src command: %s", command) - } - file := args[0] - lines := bytes.SplitAfter(readFile(file), newline) - // File plus zero args: whole file: - // !src file.go - if len(args) == 1 { - return lines - } - start := match(file, 0, lines, string(args[1])) - // File plus one arg: one line: - // !src file.go /foo/ - if len(args) == 2 { - return [][]byte{lines[start]} - } - // File plus two args: range: - // !src file.go /foo/ /^}/ - end := match(file, start, lines, string(args[2])) - return lines[start : end+1] // +1 to include matched line. -} - -// htmlEscape makes sure input is HTML clean, if necessary. -func htmlEscape(input []byte) []byte { - if !*html || bytes.IndexAny(input, `&"<>`) < 0 { - return input - } - var b bytes.Buffer - template.HTMLEscape(&b, input) - return b.Bytes() -} - -// readFile reads and returns a file as part of !src processing. -func readFile(name string) []byte { - file, err := ioutil.ReadFile(name) - if err != nil { - log.Fatal(err) - } - return file -} - -// match identifies the input line that matches the pattern in a !src invocation. -// If start>0, match lines starting there rather than at the beginning. -func match(file string, start int, lines [][]byte, pattern string) int { - // $ matches the end of the file. - if pattern == "$" { - return len(lines) - 1 - } - // Number matches the line. - if i, err := strconv.Atoi(pattern); err == nil { - return i - 1 // Lines are 1-indexed. - } - // /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.Match(lines[i]) { - return i - } - } - log.Fatalf("%s: no match for %s", file, pattern) - } - log.Fatalf("unrecognized pattern: %s", pattern) - return 0 -} - -// coalesce combines lines. Each time prefix is found on a line, -// it calls fold and replaces the line with return value from fold. -func coalesce(prefix []byte, fold func(i int) (n int, line []byte)) { - j := 0 // output line number goes up by one each loop - for i := 0; i < len(lines); { - if bytes.HasPrefix(lines[i], prefix) { - nlines, block := fold(i) - lines[j] = block - i += nlines - } else { - lines[j] = lines[i] - i++ - } - j++ - } - lines = lines[0:j] -} - -// foldPre returns the <pre> block as a single slice. -func foldPre(i int) (n int, line []byte) { - buf := new(bytes.Buffer) - for i < len(lines) { - buf.Write(lines[i]) - n++ - if bytes.Equal(lines[i], preEnd) { - break - } - i++ - } - return n, buf.Bytes() -} - -// foldTabs returns the tab-indented block as a single <pre>-bounded slice. -func foldTabs(i int) (n int, line []byte) { - buf := new(bytes.Buffer) - buf.WriteString("<pre>\n") - for i < len(lines) { - if !bytes.HasPrefix(lines[i], tab) { - break - } - buf.Write(lines[i][1:]) // delete leading tab. - n++ - i++ - } - buf.WriteString("</pre>\n") - return n, buf.Bytes() -} - -// headings turns sections into HTML sections. -func headings() { - b := bufio.NewWriter(os.Stdout) - for i, l := range lines { - if i > 0 && bytes.Equal(l, sectionMarker) { - lines[i-1] = []byte("<h2>" + string(trim(lines[i-1])) + "</h2>\n") - lines[i] = empty - } - } - b.Flush() -} - -// paragraphs turns blank lines into paragraph marks. -func paragraphs() { - for i, l := range lines { - if bytes.Equal(l, newline) { - lines[i] = pp - } - } -} - -// quotes turns "x" in the file into <code>x</code>. -func quotes() { - for i, l := range lines { - lines[i] = codeQuotes(l) - } -} - -// quotes turns "x" in the line into <code>x</code>. -func codeQuotes(l []byte) []byte { - if bytes.HasPrefix(l, preStart) { - return l - } - n := bytes.Index(l, quote) - if n < 0 { - return l - } - buf := new(bytes.Buffer) - inQuote := false - for _, c := range l { - if c == '"' { - if inQuote { - buf.WriteString("</code>") - } else { - buf.WriteString("<code>") - } - inQuote = !inQuote - } else { - buf.WriteByte(c) - } - } - return buf.Bytes() -} - -// trim drops the trailing newline, if present. -func trim(l []byte) []byte { - n := len(l) - if n > 0 && l[n-1] == '\n' { - return l[0 : n-1] - } - return l -} - -// expandTabs expands tabs to spaces. It doesn't worry about columns. -func expandTabs(l []byte) []byte { - return bytes.Replace(l, tab, indent, -1) -} diff --git a/doc/ie.css b/doc/ie.css deleted file mode 100644 index bb89d54be..000000000 --- a/doc/ie.css +++ /dev/null @@ -1 +0,0 @@ -#nav-main li { display: inline; } diff --git a/doc/install.html b/doc/install.html deleted file mode 100644 index a1bc89982..000000000 --- a/doc/install.html +++ /dev/null @@ -1,474 +0,0 @@ -<!-- 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 differdeleted file mode 100644 index 4a2446ce7..000000000 --- a/doc/logo-153x55.png +++ /dev/null diff --git a/doc/logo.png b/doc/logo.png Binary files differdeleted file mode 100644 index 076ce398e..000000000 --- a/doc/logo.png +++ /dev/null diff --git a/doc/makehtml b/doc/makehtml deleted file mode 100755 index 1b8caed69..000000000 --- a/doc/makehtml +++ /dev/null @@ -1,17 +0,0 @@ -#!/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 - -TXT=${1:-go_tutorial.txt} # input file -HTML=$(basename $TXT .txt).html # output file (basename) - -if ! test -w $HTML -then - echo 1>&2 makehtml: cannot open $HTML for write - exit 1 -fi - -make htmlgen && ./htmlgen < $TXT > $HTML diff --git a/doc/play_overlay.png b/doc/play_overlay.png Binary files differdeleted file mode 100644 index 20ef7f399..000000000 --- a/doc/play_overlay.png +++ /dev/null diff --git a/doc/playground.html b/doc/playground.html deleted file mode 100644 index 01d3adc9c..000000000 --- a/doc/playground.html +++ /dev/null @@ -1,27 +0,0 @@ -<!-- 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 deleted file mode 100644 index 23ccc8c75..000000000 --- a/doc/popups.js +++ /dev/null @@ -1,24 +0,0 @@ -// 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 deleted file mode 100644 index 9f0b8d4a3..000000000 --- a/doc/progs/cat.go +++ /dev/null @@ -1,47 +0,0 @@ -// 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 deleted file mode 100644 index 0eefe7cfc..000000000 --- a/doc/progs/cat_rot13.go +++ /dev/null @@ -1,90 +0,0 @@ -// 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 deleted file mode 100644 index 84470ddb9..000000000 --- a/doc/progs/echo.go +++ /dev/null @@ -1,32 +0,0 @@ -// 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 deleted file mode 100644 index 2875ce73a..000000000 --- a/doc/progs/file.go +++ /dev/null @@ -1,89 +0,0 @@ -// 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 deleted file mode 100644 index d5e7c00d3..000000000 --- a/doc/progs/file_windows.go +++ /dev/null @@ -1,89 +0,0 @@ -// 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 deleted file mode 100644 index 637a0956b..000000000 --- a/doc/progs/helloworld.go +++ /dev/null @@ -1,11 +0,0 @@ -// 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 deleted file mode 100644 index 5bb0be218..000000000 --- a/doc/progs/helloworld3.go +++ /dev/null @@ -1,21 +0,0 @@ -// 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 deleted file mode 100644 index 69c35a532..000000000 --- a/doc/progs/print.go +++ /dev/null @@ -1,23 +0,0 @@ -// 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 deleted file mode 100644 index 46ab1d91a..000000000 --- a/doc/progs/print_string.go +++ /dev/null @@ -1,21 +0,0 @@ -// 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 deleted file mode 100755 index 81781c9d2..000000000 --- a/doc/progs/run +++ /dev/null @@ -1,85 +0,0 @@ -#!/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 deleted file mode 100644 index f3a6b1889..000000000 --- a/doc/progs/server.go +++ /dev/null @@ -1,51 +0,0 @@ -// 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 deleted file mode 100644 index b8c09269b..000000000 --- a/doc/progs/server1.go +++ /dev/null @@ -1,56 +0,0 @@ -// 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 deleted file mode 100644 index c7c3e7812..000000000 --- a/doc/progs/sieve.go +++ /dev/null @@ -1,38 +0,0 @@ -// 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 deleted file mode 100644 index e785e2035..000000000 --- a/doc/progs/sieve1.go +++ /dev/null @@ -1,51 +0,0 @@ -// 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 deleted file mode 100644 index 47df9b351..000000000 --- a/doc/progs/sort.go +++ /dev/null @@ -1,63 +0,0 @@ -// 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 deleted file mode 100644 index 28eec8d4f..000000000 --- a/doc/progs/sortmain.go +++ /dev/null @@ -1,69 +0,0 @@ -// 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 deleted file mode 100644 index 2cdb6101a..000000000 --- a/doc/progs/strings.go +++ /dev/null @@ -1,15 +0,0 @@ -// 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 deleted file mode 100644 index 9caa799fd..000000000 --- a/doc/progs/sum.go +++ /dev/null @@ -1,21 +0,0 @@ -// 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 deleted file mode 100644 index 8d76928c8..000000000 --- a/doc/root.html +++ /dev/null @@ -1,98 +0,0 @@ -<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 differdeleted file mode 100644 index 8018ae225..000000000 --- a/doc/sieve.gif +++ /dev/null diff --git a/doc/talks/go_talk-20100112.html b/doc/talks/go_talk-20100112.html deleted file mode 100644 index 2e3643512..000000000 --- a/doc/talks/go_talk-20100112.html +++ /dev/null @@ -1,411 +0,0 @@ -<!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 deleted file mode 100644 index d5e4bc66f..000000000 --- a/doc/talks/go_talk-20100121.html +++ /dev/null @@ -1,453 +0,0 @@ -<!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 deleted file mode 100644 index 3143b079a..000000000 --- a/doc/talks/go_talk-20100323.html +++ /dev/null @@ -1,395 +0,0 @@ -<!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 differdeleted file mode 100644 index 157fd7676..000000000 --- a/doc/talks/gofrontend-gcc-summit-2010.pdf +++ /dev/null diff --git a/doc/talks/io2010/balance.go b/doc/talks/io2010/balance.go deleted file mode 100644 index b01f7468c..000000000 --- a/doc/talks/io2010/balance.go +++ /dev/null @@ -1,168 +0,0 @@ -// 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 deleted file mode 100644 index 3292c30b2..000000000 --- a/doc/talks/io2010/decrypt.go +++ /dev/null @@ -1,40 +0,0 @@ -// 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 ( - "crypto/aes" - "crypto/block" - "compress/gzip" - "io" - "os" -) - -func EncryptAndGzip(dstfile, srcfile string, key, iv []byte) { - r, _ := os.Open(srcfile, os.O_RDONLY, 0) - var w io.Writer - w, _ = os.Open(dstfile, os.O_WRONLY|os.O_CREATE, 0666) - c, _ := aes.NewCipher(key) - w = block.NewOFBWriter(c, iv, w) - w2, _ := gzip.NewDeflater(w) - io.Copy(w2, r) - w2.Close() -} - -func DecryptAndGunzip(dstfile, srcfile string, key, iv []byte) { - f, _ := os.Open(srcfile, os.O_RDONLY, 0) - defer f.Close() - c, _ := aes.NewCipher(key) - r := block.NewOFBReader(c, iv, f) - r, _ = gzip.NewInflater(r) - w, _ := os.Open(dstfile, os.O_WRONLY|os.O_CREATE, 0666) - defer w.Close() - io.Copy(w, r) -} - -func main() { - EncryptAndGzip("/tmp/passwd.gz", "/etc/passwd", make([]byte, 16), make([]byte, 16)) - DecryptAndGunzip("/dev/stdout", "/tmp/passwd.gz", make([]byte, 16), make([]byte, 16)) -} diff --git a/doc/talks/io2010/encrypt.go b/doc/talks/io2010/encrypt.go deleted file mode 100644 index e5ab3fc59..000000000 --- a/doc/talks/io2010/encrypt.go +++ /dev/null @@ -1,28 +0,0 @@ -// 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 ( - "crypto/aes" - "crypto/block" - "compress/gzip" - "io" - "os" -) - -func EncryptAndGzip(dstfile, srcfile string, key, iv []byte) { - r, _ := os.Open(srcfile, os.O_RDONLY, 0) - var w io.WriteCloser - w, _ = os.Open(dstfile, os.O_WRONLY|os.O_CREATE, 0666) - defer w.Close() - w, _ = gzip.NewDeflater(w) - defer w.Close() - c, _ := aes.NewCipher(key) - io.Copy(block.NewCBCEncrypter(c, iv, w), r) -} - -func main() { - EncryptAndGzip("/tmp/passwd.gz", "/etc/passwd", make([]byte, 16), make([]byte, 16)) -} diff --git a/doc/talks/io2010/eval1.go b/doc/talks/io2010/eval1.go deleted file mode 100644 index 2d7fc3be6..000000000 --- a/doc/talks/io2010/eval1.go +++ /dev/null @@ -1,229 +0,0 @@ -// 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 deleted file mode 100644 index 5524c8b3a..000000000 --- a/doc/talks/io2010/eval2.go +++ /dev/null @@ -1,261 +0,0 @@ -// 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 differdeleted file mode 100644 index aff42c21d..000000000 --- a/doc/talks/io2010/talk.pdf +++ /dev/null diff --git a/doc/talks/io2011/Real_World_Go.pdf b/doc/talks/io2011/Real_World_Go.pdf Binary files differdeleted file mode 100644 index 2a187116b..000000000 --- a/doc/talks/io2011/Real_World_Go.pdf +++ /dev/null diff --git a/doc/talks/io2011/Writing_Web_Apps_in_Go.pdf b/doc/talks/io2011/Writing_Web_Apps_in_Go.pdf Binary files differdeleted file mode 100644 index ca4702ee9..000000000 --- a/doc/talks/io2011/Writing_Web_Apps_in_Go.pdf +++ /dev/null diff --git a/doc/talks/java-typing.png b/doc/talks/java-typing.png Binary files differdeleted file mode 100644 index 54abf0186..000000000 --- a/doc/talks/java-typing.png +++ /dev/null diff --git a/doc/talks/slidy.css b/doc/talks/slidy.css deleted file mode 100644 index e9ff53218..000000000 --- a/doc/talks/slidy.css +++ /dev/null @@ -1,277 +0,0 @@ -/* 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 deleted file mode 100644 index 6a5561a6c..000000000 --- a/doc/talks/slidy.js +++ /dev/null @@ -1,2772 +0,0 @@ -/* 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/video-001.png b/doc/video-001.png Binary files differdeleted file mode 100644 index d3468bbe8..000000000 --- a/doc/video-001.png +++ /dev/null diff --git a/doc/video-002.png b/doc/video-002.png Binary files differdeleted file mode 100644 index 4f7c5d184..000000000 --- a/doc/video-002.png +++ /dev/null diff --git a/doc/video-003.png b/doc/video-003.png Binary files differdeleted file mode 100644 index 3dff68602..000000000 --- a/doc/video-003.png +++ /dev/null diff --git a/doc/video-004.png b/doc/video-004.png Binary files differdeleted file mode 100644 index 92144549a..000000000 --- a/doc/video-004.png +++ /dev/null diff --git a/doc/video-005.jpg b/doc/video-005.jpg Binary files differdeleted file mode 100644 index 32371581f..000000000 --- a/doc/video-005.jpg +++ /dev/null |