diff options
author | Ondřej Surý <ondrej@sury.org> | 2011-02-14 13:23:51 +0100 |
---|---|---|
committer | Ondřej Surý <ondrej@sury.org> | 2011-02-14 13:23:51 +0100 |
commit | 758ff64c69e34965f8af5b2d6ffd65e8d7ab2150 (patch) | |
tree | 6d6b34f8c678862fe9b56c945a7b63f68502c245 /doc | |
parent | 3e45412327a2654a77944249962b3652e6142299 (diff) | |
download | golang-758ff64c69e34965f8af5b2d6ffd65e8d7ab2150.tar.gz |
Imported Upstream version 2011-02-01.1upstream/2011-02-01.1
Diffstat (limited to 'doc')
34 files changed, 755 insertions, 456 deletions
diff --git a/doc/all.css b/doc/all.css index f70ef1599..b1d55cf25 100644 --- a/doc/all.css +++ b/doc/all.css @@ -157,6 +157,10 @@ h1#title { pre.ebnf, pre.grammar { background: #FFFFE0; } +span.ln { + font-size: 80%; + color: #777777; +} span.comment { color: #002090; } diff --git a/doc/codelab/wiki/Makefile b/doc/codelab/wiki/Makefile index e0549fc8e..0d948ed4b 100644 --- a/doc/codelab/wiki/Makefile +++ b/doc/codelab/wiki/Makefile @@ -13,12 +13,13 @@ CLEANFILES+=index.html srcextract.bin htmlify.bin index.html: srcextract.bin htmlify.bin awk '/^!/{system(substr($$0,2)); next} {print}' "$$@" < wiki.html > index.html -test: final.bin - ./test.sh - rm -f final.6 final.bin +test: get.bin + bash ./test.sh + rm -f get.6 get.bin %.bin: %.$O $(LD) -o $@ $< -%.$O: + +%.$O: %.go $(GC) $*.go diff --git a/doc/codelab/wiki/edit.html b/doc/codelab/wiki/edit.html index 71a919496..7a5768ce9 100644 --- a/doc/codelab/wiki/edit.html +++ b/doc/codelab/wiki/edit.html @@ -1,6 +1,6 @@ -<h1>Editing {title}</h1> +<h1>Editing {Title}</h1> -<form action="/save/{title}" method="POST"> -<div><textarea name="body" rows="20" cols="80">{body|html}</textarea></div> +<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 index 2f48565ca..99121f298 100644 --- a/doc/codelab/wiki/final-noclosure.go +++ b/doc/codelab/wiki/final-noclosure.go @@ -8,23 +8,23 @@ import ( "template" ) -type page struct { - title string - body []byte +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 (p *Page) save() os.Error { + filename := p.Title + ".txt" + return ioutil.WriteFile(filename, p.Body, 0600) } -func loadPage(title string) (*page, os.Error) { +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 + return &Page{Title: title, Body: body}, nil } func viewHandler(w http.ResponseWriter, r *http.Request) { @@ -47,7 +47,7 @@ func editHandler(w http.ResponseWriter, r *http.Request) { } p, err := loadPage(title) if err != nil { - p = &page{title: title} + p = &Page{Title: title} } renderTemplate(w, "edit", p) } @@ -58,7 +58,7 @@ func saveHandler(w http.ResponseWriter, r *http.Request) { return } body := r.FormValue("body") - p := &page{title: title, body: []byte(body)} + p := &Page{Title: title, Body: []byte(body)} err = p.save() if err != nil { http.Error(w, err.String(), http.StatusInternalServerError) @@ -67,7 +67,7 @@ func saveHandler(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, "/view/"+title, http.StatusFound) } -func renderTemplate(w http.ResponseWriter, tmpl string, p *page) { +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) diff --git a/doc/codelab/wiki/final-noerror.go b/doc/codelab/wiki/final-noerror.go index cf4852265..0f18912d2 100644 --- a/doc/codelab/wiki/final-noerror.go +++ b/doc/codelab/wiki/final-noerror.go @@ -7,23 +7,23 @@ import ( "template" ) -type page struct { - title string - body []byte +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 (p *Page) save() os.Error { + filename := p.Title + ".txt" + return ioutil.WriteFile(filename, p.Body, 0600) } -func loadPage(title string) (*page, os.Error) { +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 + return &Page{Title: title, Body: body}, nil } const lenPath = len("/view/") @@ -32,7 +32,7 @@ func editHandler(w http.ResponseWriter, r *http.Request) { title := r.URL.Path[lenPath:] p, err := loadPage(title) if err != nil { - p = &page{title: title} + p = &Page{Title: title} } t, _ := template.ParseFile("edit.html", nil) t.Execute(p, w) diff --git a/doc/codelab/wiki/final-parsetemplate.go b/doc/codelab/wiki/final-parsetemplate.go index f02d116b2..ea8977601 100644 --- a/doc/codelab/wiki/final-parsetemplate.go +++ b/doc/codelab/wiki/final-parsetemplate.go @@ -8,23 +8,23 @@ import ( "template" ) -type page struct { - title string - body []byte +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 (p *Page) save() os.Error { + filename := p.Title + ".txt" + return ioutil.WriteFile(filename, p.Body, 0600) } -func loadPage(title string) (*page, os.Error) { +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 + return &Page{Title: title, Body: body}, nil } func viewHandler(w http.ResponseWriter, r *http.Request, title string) { @@ -39,14 +39,14 @@ func viewHandler(w http.ResponseWriter, r *http.Request, title string) { func editHandler(w http.ResponseWriter, r *http.Request, title string) { p, err := loadPage(title) if err != nil { - p = &page{title: title} + 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)} + p := &Page{Title: title, Body: []byte(body)} err := p.save() if err != nil { http.Error(w, err.String(), http.StatusInternalServerError) @@ -55,7 +55,7 @@ func saveHandler(w http.ResponseWriter, r *http.Request, title string) { http.Redirect(w, r, "/view/"+title, http.StatusFound) } -func renderTemplate(w http.ResponseWriter, tmpl string, p *page) { +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) diff --git a/doc/codelab/wiki/final-template.go b/doc/codelab/wiki/final-template.go index 0bb133d3a..4d6a2cfab 100644 --- a/doc/codelab/wiki/final-template.go +++ b/doc/codelab/wiki/final-template.go @@ -7,23 +7,23 @@ import ( "template" ) -type page struct { - title string - body []byte +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 (p *Page) save() os.Error { + filename := p.Title + ".txt" + return ioutil.WriteFile(filename, p.Body, 0600) } -func loadPage(title string) (*page, os.Error) { +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 + return &Page{Title: title, Body: body}, nil } const lenPath = len("/view/") @@ -32,7 +32,7 @@ func editHandler(w http.ResponseWriter, r *http.Request) { title := r.URL.Path[lenPath:] p, err := loadPage(title) if err != nil { - p = &page{title: title} + p = &Page{Title: title} } renderTemplate(w, "edit", p) } @@ -46,12 +46,12 @@ func viewHandler(w http.ResponseWriter, r *http.Request) { 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 := &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) { +func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) { t, _ := template.ParseFile(tmpl+".html", nil) t.Execute(p, w) } diff --git a/doc/codelab/wiki/final.go b/doc/codelab/wiki/final.go index 0c0206bc0..8ecd97d74 100644 --- a/doc/codelab/wiki/final.go +++ b/doc/codelab/wiki/final.go @@ -8,23 +8,23 @@ import ( "template" ) -type page struct { - title string - body []byte +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 (p *Page) save() os.Error { + filename := p.Title + ".txt" + return ioutil.WriteFile(filename, p.Body, 0600) } -func loadPage(title string) (*page, os.Error) { +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 + return &Page{Title: title, Body: body}, nil } func viewHandler(w http.ResponseWriter, r *http.Request, title string) { @@ -39,14 +39,14 @@ func viewHandler(w http.ResponseWriter, r *http.Request, title string) { func editHandler(w http.ResponseWriter, r *http.Request, title string) { p, err := loadPage(title) if err != nil { - p = &page{title: title} + 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)} + p := &Page{Title: title, Body: []byte(body)} err := p.save() if err != nil { http.Error(w, err.String(), http.StatusInternalServerError) @@ -63,7 +63,7 @@ func init() { } } -func renderTemplate(w http.ResponseWriter, tmpl string, p *page) { +func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) { err := templates[tmpl].Execute(p, w) if err != nil { http.Error(w, err.String(), http.StatusInternalServerError) diff --git a/doc/codelab/wiki/get.go b/doc/codelab/wiki/get.go new file mode 100644 index 000000000..342831416 --- /dev/null +++ b/doc/codelab/wiki/get.go @@ -0,0 +1,50 @@ +package main + +import ( + "http" + "flag" + "fmt" + "io" + "log" + "net" + "os" + "strings" +) + +var ( + post = flag.String("post", "", "urlencoded form data to POST") + addr = flag.Bool("addr", false, "find open address and print to stdout") +) + +func main() { + flag.Parse() + if *addr { + l, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + log.Fatal(err) + } + defer l.Close() + fmt.Print(l.Addr()) + return + } + url := flag.Arg(0) + if url == "" { + log.Fatal("no url supplied") + } + var r *http.Response + var err os.Error + if *post != "" { + b := strings.NewReader(*post) + r, err = http.Post(url, "application/x-www-form-urlencoded", b) + } else { + r, _, err = http.Get(url) + } + if err != nil { + log.Fatal(err) + } + defer r.Body.Close() + _, err = io.Copy(os.Stdout, r.Body) + if err != nil { + log.Fatal(err) + } +} diff --git a/doc/codelab/wiki/htmlify.go b/doc/codelab/wiki/htmlify.go index 4a52e077f..456d06fd5 100644 --- a/doc/codelab/wiki/htmlify.go +++ b/doc/codelab/wiki/htmlify.go @@ -8,5 +8,5 @@ import ( func main() { b, _ := ioutil.ReadAll(os.Stdin) - template.HTMLFormatter(os.Stdout, b, "") + template.HTMLFormatter(os.Stdout, "", b) } diff --git a/doc/codelab/wiki/index.html b/doc/codelab/wiki/index.html index c494a3ced..fe99c32d1 100644 --- a/doc/codelab/wiki/index.html +++ b/doc/codelab/wiki/index.html @@ -71,14 +71,14 @@ declaration. <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 +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 +type Page struct { + Title string + Body []byte } </pre> @@ -86,33 +86,33 @@ type page struct { 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 +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. +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>: +<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) +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 +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. +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> @@ -120,7 +120,7 @@ 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 +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> @@ -137,17 +137,17 @@ We will want to load pages, too: </p> <pre> -func loadPage(title string) *page { +func loadPage(title string) *Page { filename := title + ".txt" body, _ := ioutil.ReadFile(filename) - return &page{title: title, body: body} + 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>. +<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> @@ -161,23 +161,23 @@ error return value (in essence, assigning the value to nothing). <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>. +function to return <code>*Page</code> and <code>os.Error</code>. </p> <pre> -func loadPage(title string) (*page, os.Error) { +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 + 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>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). @@ -191,17 +191,17 @@ written: <pre> func main() { - p1 := &page{title: "TestPage", body: []byte("This is a sample page.")} + p1 := &Page{Title: "TestPage", Body: []byte("This is a sample Page.")} p1.save() p2, _ := loadPage("TestPage") - fmt.Println(string(p2.body)) + 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 +then be read into the struct <code>p2</code>, and its <code>Body</code> element printed to the screen. </p> @@ -317,7 +317,7 @@ 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) + fmt.Fprintf(w, "<h1>%s</h1><div>%s</div>", p.Title, p.Body) } </pre> @@ -377,7 +377,7 @@ 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> +<h2>Editing Pages</h2> <p> A wiki is not a wiki without the ability to edit pages. Let's create two new @@ -401,7 +401,7 @@ func main() { <p> The function <code>editHandler</code> loads the page -(or, if it doesn't exist, create an empty <code>page</code> struct), +(or, if it doesn't exist, create an empty <code>Page</code> struct), and displays an HTML form. </p> @@ -410,14 +410,14 @@ func editHandler(w http.ResponseWriter, r *http.Request) { title := r.URL.Path[lenPath:] p, err := loadPage(title) if err != nil { - p = &page{title: title} + 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) + p.Title, p.Title, p.Body) } </pre> @@ -454,10 +454,10 @@ Open a new file named <code>edit.html</code>, and add the following lines: </p> <pre> -<h1>Editing {title}</h1> +<h1>Editing {Title}</h1> -<form action="/save/{title}" method="POST"> -<div><textarea name="body" rows="20" cols="80">{body|html}</textarea></div> +<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> @@ -472,7 +472,7 @@ func editHandler(w http.ResponseWriter, r *http.Request) { title := r.URL.Path[lenPath:] p, err := loadPage(title) if err != nil { - p = &page{title: title} + p = &Page{Title: title} } t, _ := template.ParseFile("edit.html", nil) t.Execute(p, w) @@ -486,15 +486,15 @@ The function <code>template.ParseFile</code> will read the contents of <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 +<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. +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, +<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. @@ -511,11 +511,11 @@ While we're working with templates, let's create a template for our </p> <pre> -<h1>{title}</h1> +<h1>{Title}</h1> -<p>[<a href="/edit/{title}">edit</a>]</p> +<p>[<a href="/edit/{Title}">edit</a>]</p> -<div>{body}</div> +<div>{Body}</div> </pre> <p> @@ -548,12 +548,12 @@ func editHandler(w http.ResponseWriter, r *http.Request) { title := r.URL.Path[lenPath:] p, err := loadPage(title) if err != nil { - p = &page{title: title} + p = &Page{Title: title} } renderTemplate(w, "edit", p) } -func renderTemplate(w http.ResponseWriter, tmpl string, p *page) { +func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) { t, _ := template.ParseFile(tmpl+".html", nil) t.Execute(p, w) } @@ -568,8 +568,8 @@ The handlers are now shorter and simpler. <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: +<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> @@ -589,7 +589,7 @@ The <code>http.Redirect</code> function adds an HTTP status code of header to the HTTP response. </p> -<h2>Saving pages</h2> +<h2>Saving Pages</h2> <p> The function <code>saveHandler</code> will handle the form submission. @@ -599,7 +599,7 @@ The function <code>saveHandler</code> will handle the form submission. 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 := &Page{Title: title, Body: []byte(body)} p.save() http.Redirect(w, r, "/view/"+title, http.StatusFound) } @@ -607,7 +607,7 @@ func saveHandler(w http.ResponseWriter, r *http.Request) { <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>. +<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> @@ -615,7 +615,7 @@ and the client is redirected to the <code>/view/</code> page. <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 <code>Page</code> struct. We use <code>[]byte(body)</code> to perform the conversion. </p> @@ -634,7 +634,7 @@ First, let's handle the errors in <code>renderTemplate</code>: </p> <pre> -func renderTemplate(w http.ResponseWriter, tmpl string, p *page) { +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) @@ -660,7 +660,7 @@ Now let's fix up <code>saveHandler</code>: <pre> func saveHandler(w http.ResponseWriter, r *http.Request, title string) { body := r.FormValue("body") - p := &page{title: title, body: []byte(body)} + p := &Page{Title: title, Body: []byte(body)} err := p.save() if err != nil { http.Error(w, err.String(), http.StatusInternalServerError) @@ -725,7 +725,7 @@ 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) { +func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) { err := templates[tmpl].Execute(p, w) if err != nil { http.Error(w, err.String(), http.StatusInternalServerError) @@ -747,7 +747,6 @@ Then we can create a global variable to store our validation regexp: </p> <pre> -var titleValidator = regexp.MustCompile("^[a-zA-Z0-9]+$") </pre> <p> @@ -761,7 +760,7 @@ the expression compilation fails, while <code>Compile</code> returns an <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: +URL, and tests it against our <code>TitleValidator</code> expression: </p> <pre> @@ -807,7 +806,7 @@ func editHandler(w http.ResponseWriter, r *http.Request) { } p, err := loadPage(title) if err != nil { - p = &page{title: title} + p = &Page{Title: title} } renderTemplate(w, "edit", p) } @@ -818,7 +817,7 @@ func saveHandler(w http.ResponseWriter, r *http.Request) { return } body := r.FormValue("body") - p := &page{title: title, body: []byte(body)} + p := &Page{Title: title, Body: []byte(body)} err = p.save() if err != nil { http.Error(w, err.String(), http.StatusInternalServerError) @@ -895,7 +894,7 @@ 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 +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 @@ -936,14 +935,14 @@ func viewHandler(w http.ResponseWriter, r *http.Request, title string) { func editHandler(w http.ResponseWriter, r *http.Request, title string) { p, err := loadPage(title) if err != nil { - p = &page{title: title} + 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)} + p := &Page{Title: title, Body: []byte(body)} err := p.save() if err != nil { http.Error(w, err.String(), http.StatusInternalServerError) diff --git a/doc/codelab/wiki/notemplate.go b/doc/codelab/wiki/notemplate.go index c1f952c83..9cbe9ad76 100644 --- a/doc/codelab/wiki/notemplate.go +++ b/doc/codelab/wiki/notemplate.go @@ -7,23 +7,23 @@ import ( "os" ) -type page struct { - title string - body []byte +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 (p *Page) save() os.Error { + filename := p.Title + ".txt" + return ioutil.WriteFile(filename, p.Body, 0600) } -func loadPage(title string) (*page, os.Error) { +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 + return &Page{Title: title, Body: body}, nil } const lenPath = len("/view/") @@ -31,21 +31,21 @@ 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) + 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} + 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) + p.Title, p.Title, p.Body) } func main() { diff --git a/doc/codelab/wiki/part1-noerror.go b/doc/codelab/wiki/part1-noerror.go index 39e8331e3..14cfc321a 100644 --- a/doc/codelab/wiki/part1-noerror.go +++ b/doc/codelab/wiki/part1-noerror.go @@ -6,25 +6,25 @@ import ( "os" ) -type page struct { - title string - body []byte +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 (p *Page) save() os.Error { + filename := p.Title + ".txt" + return ioutil.WriteFile(filename, p.Body, 0600) } -func loadPage(title string) *page { +func loadPage(title string) *Page { filename := title + ".txt" body, _ := ioutil.ReadFile(filename) - return &page{title: title, body: body} + return &Page{Title: title, Body: body} } func main() { - p1 := &page{title: "TestPage", body: []byte("This is a sample page.")} + p1 := &Page{Title: "TestPage", Body: []byte("This is a sample page.")} p1.save() p2 := loadPage("TestPage") - fmt.Println(string(p2.body)) + fmt.Println(string(p2.Body)) } diff --git a/doc/codelab/wiki/part1.go b/doc/codelab/wiki/part1.go index f3678baa5..4b0654f8b 100644 --- a/doc/codelab/wiki/part1.go +++ b/doc/codelab/wiki/part1.go @@ -6,28 +6,28 @@ import ( "os" ) -type page struct { - title string - body []byte +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 (p *Page) save() os.Error { + filename := p.Title + ".txt" + return ioutil.WriteFile(filename, p.Body, 0600) } -func loadPage(title string) (*page, os.Error) { +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 + return &Page{Title: title, Body: body}, nil } func main() { - p1 := &page{title: "TestPage", body: []byte("This is a sample page.")} + p1 := &Page{Title: "TestPage", Body: []byte("This is a sample Page.")} p1.save() p2, _ := loadPage("TestPage") - fmt.Println(string(p2.body)) + fmt.Println(string(p2.Body)) } diff --git a/doc/codelab/wiki/part2.go b/doc/codelab/wiki/part2.go index 8d4454a74..d57c3a01f 100644 --- a/doc/codelab/wiki/part2.go +++ b/doc/codelab/wiki/part2.go @@ -7,23 +7,23 @@ import ( "os" ) -type page struct { - title string - body []byte +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 (p *Page) save() os.Error { + filename := p.Title + ".txt" + return ioutil.WriteFile(filename, p.Body, 0600) } -func loadPage(title string) (*page, os.Error) { +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 + return &Page{Title: title, Body: body}, nil } const lenPath = len("/view/") @@ -31,7 +31,7 @@ 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) + fmt.Fprintf(w, "<h1>%s</h1><div>%s</div>", p.Title, p.Body) } func main() { diff --git a/doc/codelab/wiki/srcextract.go b/doc/codelab/wiki/srcextract.go index 0addc61c4..cab092f58 100644 --- a/doc/codelab/wiki/srcextract.go +++ b/doc/codelab/wiki/srcextract.go @@ -6,6 +6,7 @@ import ( "go/parser" "go/printer" "go/ast" + "go/token" "log" "os" ) @@ -25,9 +26,10 @@ func main() { os.Exit(2) } // load file - file, err := parser.ParseFile(*srcFn, nil, 0) + fs := token.NewFileSet() + file, err := parser.ParseFile(fs, *srcFn, nil, 0) if err != nil { - log.Exit(err) + log.Fatal(err) } // create printer p := &printer.Config{ @@ -47,7 +49,7 @@ func main() { os.Exit(1) } b := new(bytes.Buffer) - p.Fprint(b, file) + p.Fprint(b, fs, file) // drop package declaration if !*showPkg { for { diff --git a/doc/codelab/wiki/test.sh b/doc/codelab/wiki/test.sh index 5b752fe3c..95ff145b9 100755 --- a/doc/codelab/wiki/test.sh +++ b/doc/codelab/wiki/test.sh @@ -1,24 +1,27 @@ -#1/bin/bash - -./final.bin & -wiki_pid=$! +#!/usr/bin/env bash +set -e +wiki_pid= cleanup() { kill $wiki_pid - rm -f test_*.out Test.txt - exit ${1:-1} + rm -f test_*.out Test.txt final-test.bin final-test.go } -trap cleanup INT +trap cleanup 0 INT -sleep 1 +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=$! -curl -s -o test_edit.out http://localhost:8080/edit/Test -cmp test_edit.out test_edit.good || cleanup 1 -curl -s -o /dev/null -d body=some%20content http://localhost:8080/save/Test -cmp Test.txt test_Test.txt.good || cleanup 1 -curl -s -o test_view.out http://localhost:8080/view/Test -cmp test_view.out test_view.good || cleanup 1 +sleep 1 -echo "Passed" -cleanup 0 +./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/view.html b/doc/codelab/wiki/view.html index a46622d01..ca2ffc20b 100644 --- a/doc/codelab/wiki/view.html +++ b/doc/codelab/wiki/view.html @@ -1,5 +1,5 @@ -<h1>{title}</h1> +<h1>{Title}</h1> -<p>[<a href="/edit/{title}">edit</a>]</p> +<p>[<a href="/edit/{Title}">edit</a>]</p> -<div>{body}</div> +<div>{Body}</div> diff --git a/doc/codelab/wiki/wiki.html b/doc/codelab/wiki/wiki.html index 919385edf..ff2c3088b 100644 --- a/doc/codelab/wiki/wiki.html +++ b/doc/codelab/wiki/wiki.html @@ -71,27 +71,27 @@ declaration. <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 +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 +!./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 +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. +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>: +<code>save</code> method on <code>Page</code>: </p> <pre> @@ -100,13 +100,13 @@ But what about persistent storage? We can address that by creating a <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 +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. +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> @@ -114,7 +114,7 @@ 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 +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> @@ -136,8 +136,8 @@ We will want to load pages, too: <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>. +<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> @@ -151,7 +151,7 @@ error return value (in essence, assigning the value to nothing). <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>. +function to return <code>*Page</code> and <code>os.Error</code>. </p> <pre> @@ -160,7 +160,7 @@ function to return <code>*page</code> and <code>os.Error</code>. <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>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). @@ -179,7 +179,7 @@ written: <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 +then be read into the struct <code>p2</code>, and its <code>Body</code> element printed to the screen. </p> @@ -334,7 +334,7 @@ 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> +<h2>Editing Pages</h2> <p> A wiki is not a wiki without the ability to edit pages. Let's create two new @@ -353,7 +353,7 @@ First, we add them to <code>main()</code>: <p> The function <code>editHandler</code> loads the page -(or, if it doesn't exist, create an empty <code>page</code> struct), +(or, if it doesn't exist, create an empty <code>Page</code> struct), and displays an HTML form. </p> @@ -413,15 +413,15 @@ The function <code>template.ParseFile</code> will read the contents of <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 +<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. +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, +<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. @@ -472,8 +472,8 @@ The handlers are now shorter and simpler. <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: +<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> @@ -486,7 +486,7 @@ The <code>http.Redirect</code> function adds an HTTP status code of header to the HTTP response. </p> -<h2>Saving pages</h2> +<h2>Saving Pages</h2> <p> The function <code>saveHandler</code> will handle the form submission. @@ -498,7 +498,7 @@ The function <code>saveHandler</code> will handle the form submission. <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>. +<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> @@ -506,7 +506,7 @@ and the client is redirected to the <code>/view/</code> page. <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 <code>Page</code> struct. We use <code>[]byte(body)</code> to perform the conversion. </p> @@ -610,7 +610,7 @@ Then we can create a global variable to store our validation regexp: </p> <pre> -!./srcextract.bin -src=final-noclosure.go -name=titleValidator +!./srcextract.bin -src=final-noclosure.go -name=TitleValidator </pre> <p> @@ -624,7 +624,7 @@ the expression compilation fails, while <code>Compile</code> returns an <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: +URL, and tests it against our <code>TitleValidator</code> expression: </p> <pre> @@ -708,7 +708,7 @@ 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 +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 diff --git a/doc/devel/release.html b/doc/devel/release.html index ecf125953..f965b5cad 100644 --- a/doc/devel/release.html +++ b/doc/devel/release.html @@ -5,6 +5,220 @@ <p>This page summarizes the changes between tagged releases of Go. For full details, see the <a href="http://code.google.com/p/go/source/list">Mercurial change log</a>.</p> +<h3 id="2011-02-01">2011-02-01</h3> + +<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> + +<h3 id="2011-01-20">2011-01-20</h3> + +<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> + +<h3 id="2011-01-19">2011-01-19</h3> + +<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> + <h3 id="2011-01-12">2011-01-12</h3> <pre> @@ -118,16 +332,16 @@ outstanding cgo issues were resolved. <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 +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 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 smtp's StartTLS now takes a *tls.Config argument. -Package reflect’s ArrayCopy has been renamed to Copy. There are new functions +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. @@ -261,7 +475,7 @@ 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: +"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) @@ -286,8 +500,8 @@ or 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”. +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: @@ -425,12 +639,12 @@ 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: +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}} + 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}} + map[string]Point{"x": {1.5, -3.5}, "y": {0, 0}} Gofmt can make these simplifications mechanically when invoked with the new -s flag. @@ -446,8 +660,8 @@ 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 +(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. @@ -543,7 +757,7 @@ For full details, see the change description: 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. +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. diff --git a/doc/devel/roadmap.html b/doc/devel/roadmap.html index 021ed6478..9a3c4eaba 100644 --- a/doc/devel/roadmap.html +++ b/doc/devel/roadmap.html @@ -58,8 +58,6 @@ Implement goto restrictions. <li> Improved optimization. <li> -5g: Better floating point support. -<li> Use escape analysis to keep more data on stack. </ul> @@ -106,5 +104,6 @@ Public continuous build and benchmark infrastructure (gobuilder). Package manager (goinstall). <li> A means of recovering from a panic (recover). +<li> +5g: Better floating point support. </ul> - diff --git a/doc/effective_go.html b/doc/effective_go.html index 26e317b5d..3f6f89b8b 100644 --- a/doc/effective_go.html +++ b/doc/effective_go.html @@ -1124,14 +1124,14 @@ you can pass a pointer to the array. </p> <pre> -func Sum(a *[3]float) (sum float) { +func Sum(a *[3]float64) (sum float64) { for _, v := range *a { sum += v } return } -array := [...]float{7.0, 8.5, 9.1} +array := [...]float64{7.0, 8.5, 9.1} x := Sum(&array) // Note the explicit address-of operator </pre> @@ -1233,7 +1233,8 @@ 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, -floats, strings, pointers, and interfaces (as long as the dynamic type +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 @@ -1652,7 +1653,7 @@ correctness of the program state before real execution begins. <pre> func init() { if USER == "" { - log.Exit("$USER not set") + log.Fatal("$USER not set") } if HOME == "" { HOME = "/usr/" + USER @@ -1806,7 +1807,7 @@ 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 float, that +(There are other legal conversions, such as from integer to floating point, that do create a new value.) </p> <p> @@ -2525,39 +2526,49 @@ var serverChan = make(chan *Buffer) func client() { for { - b, ok := <-freeList // grab a buffer if available - if !ok { // if not, allocate a new one + 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 + load(b) // Read next message from the net. + serverChan <- b // Send to server. } } </pre> <p> -The server loop receives messages from the client, processes them, +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 + b := <-serverChan // Wait for work. process(b) - _ = freeList <- b // reuse buffer if room + // 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's non-blocking receive from <code>freeList</code> obtains a -buffer if one is available; otherwise the client allocates -a fresh one. -The server's non-blocking send on freeList puts <code>b</code> back +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 assignment of the send operation to the blank identifier -makes it non-blocking but ignores whether -the operation succeeded.) +(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. @@ -2860,7 +2871,7 @@ func main() { http.Handle("/", http.HandlerFunc(QR)) err := http.ListenAndServe(*addr, nil) if err != nil { - log.Exit("ListenAndServe:", err) + log.Fatal("ListenAndServe:", err) } } diff --git a/doc/gccgo_install.html b/doc/gccgo_install.html index 393e57963..2ab6dcdae 100644 --- a/doc/gccgo_install.html +++ b/doc/gccgo_install.html @@ -296,8 +296,8 @@ than one value, the C function returns a struct. For example, these functions have equivalent types: <pre> -func GoFunction(int) (int, float) -struct { int i; float f; } CFunction(int) +func GoFunction(int) (int, float64) +struct { int i; float64 f; } CFunction(int) </pre> <p> diff --git a/doc/go_faq.html b/doc/go_faq.html index 1c7b85ef8..3f9c1d246 100644 --- a/doc/go_faq.html +++ b/doc/go_faq.html @@ -665,11 +665,16 @@ of Effective Go</a> for more details. Why is <code>int</code> 32 bits on 64 bit machines?</h3> <p> -The size of <code>int</code> and <code>float</code> is implementation-specific. +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 -both <code>int</code> and <code>float</code>. Code that relies on a particular -size of value should use an explicitly sized type, like <code>int64</code> or -<code>float64</code>. +<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> <h2 id="Concurrency">Concurrency</h2> @@ -788,7 +793,7 @@ Consider the following program: func main() { done := make(chan bool) - values = []string{ "a", "b", "c" } + values := []string{ "a", "b", "c" } for _, v := range values { go func() { fmt.Println(v) @@ -797,7 +802,7 @@ func main() { } // wait for all goroutines to complete before exiting - for i := range values { + for _ = range values { <-done } } @@ -818,7 +823,7 @@ could modify the inner loop to read: <pre> for _, v := range values { - go func(<b>u</b>) { + go func(<b>u</b> string) { fmt.Println(<b>u</b>) done <- true }(<b>v</b>) diff --git a/doc/go_for_cpp_programmers.html b/doc/go_for_cpp_programmers.html index fae2ec44e..608ab147b 100644 --- a/doc/go_for_cpp_programmers.html +++ b/doc/go_for_cpp_programmers.html @@ -107,7 +107,7 @@ parentheses. <pre> var ( i int - m float + m float64 ) </pre> diff --git a/doc/go_spec.html b/doc/go_spec.html index e1c7e90e2..4e5d9c639 100644 --- a/doc/go_spec.html +++ b/doc/go_spec.html @@ -1,5 +1,5 @@ <!-- title The Go Programming Language Specification --> -<!-- subtitle Version of January 7, 2011 --> +<!-- subtitle Version of February 1, 2011 --> <!-- TODO @@ -11,7 +11,7 @@ TODO (struct{T} vs struct {T T} vs struct {t T}) [ ] need explicit language about the result type of operations [ ] may want to have some examples for the types of shift operations -[ ] should string(1<<s) and float(1<<s) be valid? +[ ] should string(1<<s) and float32(1<<s) be valid? [ ] should probably write something about evaluation order of statements even though obvious [ ] review language on implicit dereferencing @@ -531,7 +531,7 @@ the result value of some built-in functions such as <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>cmplx</code> applied to numeric constants. +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. @@ -561,7 +561,7 @@ or <a href="#Conversions">conversion</a>, or implicitly when used in a <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 accurately represented as a value of the respective type. +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 @@ -699,9 +699,7 @@ There is also a set of predeclared numeric types with implementation-specific si <pre class="grammar"> uint either 32 or 64 bits -int either 32 or 64 bits -float either 32 or 64 bits -complex real and imaginary parts have type float +int same size as uint uintptr an unsigned integer large enough to store the uninterpreted bits of a pointer value </pre> @@ -871,8 +869,8 @@ struct {} // A struct with 6 fields. struct { x, y int - u float - _ float // padding + u float32 + _ float32 // padding A *[]int F func() } @@ -1007,10 +1005,10 @@ func() func(x int) func() int func(prefix string, values ...int) -func(a, b int, z float) bool -func(a, b int, z float) (bool) -func(a, b int, z float, opt ...interface{}) (success bool) -func(int, int, float) (float, *[]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> @@ -1146,7 +1144,7 @@ failure will cause a <a href="#Run_time_panics">run-time panic</a>. <pre> map [string] int -map [*T] struct { x, y float } +map [*T] struct { x, y float64 } map [string] interface {} </pre> @@ -1197,7 +1195,7 @@ A channel may be constrained only to send or only to receive by <pre> chan T // can be used to send and receive values of type T -chan<- float // can only be used to send floats +chan<- float64 // can only be used to send float64s <-chan int // can only be used to receive ints </pre> @@ -1291,8 +1289,8 @@ type ( T1 []string T2 struct { a, b int } T3 struct { a, c int } - T4 func(int, float) *T0 - T5 func(x int, y float) *[]string + T4 func(int, float64) *T0 + T5 func(x int, y float64) *[]string ) </pre> @@ -1304,13 +1302,13 @@ these types are identical: T0 and T0 []int and []int struct { a, b *T5 } and struct { a, b *T5 } -func(x int, y float) *[]string and func(int, float) (result *[]string) +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, float) *T0</code> and -<code>func(x int, y float) *[]string</code> are different because <code>T0</code> +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> @@ -1483,7 +1481,7 @@ Basic types: int8 int16 int32 int64 string uint8 uint16 uint32 uint64 Architecture-specific convenience types: - complex float int uint uintptr + int uint uintptr Constants: true false iota @@ -1492,7 +1490,7 @@ Zero value: nil Functions: - append cap close closed cmplx copy imag len + append cap close closed complex copy imag len make new panic print println real recover </pre> @@ -1561,7 +1559,7 @@ const ( 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 float = 0, 3 // u = 0.0, v = 3.0 +const u, v float32 = 0, 3 // u = 0.0, v = 3.0 </pre> <p> @@ -1614,9 +1612,9 @@ const ( ) const ( - u = iota * 42 // u == 0 (untyped integer constant) - v float = iota * 42 // v == 42.0 (float constant) - w = iota * 42 // w == 84 (untyped integer constant) + 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) @@ -1736,9 +1734,9 @@ VarSpec = IdentifierList ( Type [ "=" ExpressionList ] | "=" ExpressionList <pre> var i int -var U, V, W float +var U, V, W float64 var k = 0 -var x, y float = -1, -2 +var x, y float32 = -1, -2 var ( i int u, v, s = 2.0, 3.0, "bar" @@ -1763,7 +1761,7 @@ of the expression list. <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>float</code>, or <code>string</code> +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> @@ -1771,7 +1769,7 @@ floating-point, or string constant: <pre> var b = true // t has type bool var i = 0 // i has type int -var f = 3.0 // f has type float +var f = 3.0 // f has type float64 var s = "OMDB" // s has type string </pre> @@ -2055,7 +2053,7 @@ For array and slice literals the following rules apply: <p> Taking the address of a composite literal (§<a href="#Address_operators">Address operators</a>) -generates a unique pointer to an instance of the literal's value. +generates a pointer to a unique instance of the literal's value. </p> <pre> var pointer *Point3D = &Point3D{y: 1000} @@ -2132,11 +2130,11 @@ 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]float{-1, 0, 0, 0, -0.1, -0.1, 0, 0, 0, -1} -filter := [10]float{-1, 4: -0.1, -0.1, 9: -1} +// 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]float{ +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, } @@ -2155,7 +2153,7 @@ FunctionLit = FunctionType Body . </pre> <pre> -func(a, b int, z float) bool { return a*b < int(z) } +func(a, b int, z float64) bool { return a*b < int(z) } </pre> <p> @@ -2590,7 +2588,7 @@ func Join(s, t string) string { } if Join(Split(value, len(value)/2)) != value { - log.Crash("test fails") + log.Panic("test fails") } </pre> @@ -2669,9 +2667,7 @@ Operators combine operands into expressions. Expression = UnaryExpr | Expression binary_op UnaryExpr . UnaryExpr = PrimaryExpr | unary_op UnaryExpr . -binary_op = log_op | com_op | rel_op | add_op | mul_op . -log_op = "||" | "&&" . -com_op = "<-" . +binary_op = "||" | "&&" | rel_op | add_op | mul_op . rel_op = "==" | "!=" | "<" | "<=" | ">" | ">=" . add_op = "+" | "-" | "|" | "^" . mul_op = "*" | "/" | "%" | "<<" | ">>" | "&" | "&^" . @@ -2713,11 +2709,11 @@ the left operand alone. <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 u = uint64(1<<s) // 1 has type uint64; u == 1<<33 -var f = float(1<<s) // illegal: 1 has type float, cannot shift -var g = float(1<<33) // legal; 1<<33 is a constant shift operation; g == 1<<33 +var i = 1<<s // 1 has type int +var j = int32(1<<s) // 1 has type int32; j == 0 +var u = uint64(1<<s) // 1 has type uint64; u == 1<<33 +var f = float32(1<<s) // illegal: 1 has type float32, cannot shift +var g = float32(1<<33) // legal; 1<<33 is a constant shift operation; g == 1<<33 </pre> <h3 id="Operator_precedence">Operator precedence</h3> @@ -2728,18 +2724,17 @@ 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 six precedence levels for binary operators. +There are five precedence levels for binary operators. Multiplication operators bind strongest, followed by addition -operators, comparison operators, <code><-</code> (channel send), -<code>&&</code> (logical and), and finally <code>||</code> (logical or): +operators, comparison operators, <code>&&</code> (logical and), +and finally <code>||</code> (logical or): </p> <pre class="grammar"> Precedence Operator - 6 * / % << >> & &^ - 5 + - | ^ - 4 == != < <= > >= - 3 <- + 5 * / % << >> & &^ + 4 + - | ^ + 3 == != < <= > >= 2 && 1 || </pre> @@ -2985,15 +2980,19 @@ The right operand is evaluated conditionally. <h3 id="Address_operators">Address operators</h3> <p> -The address-of operator <code>&</code> generates the address of its operand, -which must be <i>addressable</i>, +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; +operation; or a field selector of an addressable struct operand; or an array indexing operation of an addressable array. -Given an operand of pointer type, the pointer indirection -operator <code>*</code> retrieves the value pointed -to by the operand. +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> @@ -3003,76 +3002,28 @@ to by the operand. *pf(x) </pre> -<h3 id="Communication_operators">Communication operators</h3> - -<p> -The term <i>channel</i> means "value of <a href="#Channel_types">channel type</a>". -</p> -<p> -The send operation uses the binary operator "<-", which operates on -a channel and a value (expression): -</p> - -<pre> -ch <- 3 -</pre> - -<p> -The send operation sends the value on the channel. Both the channel -and the 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. -</p> -<p> -If the send operation appears in an expression context, the value -of the expression is a boolean and the operation is non-blocking. -The value of the boolean reports true if the communication succeeded, -false if it did not. (The channel and -the expression to be sent are evaluated regardless.) -These two examples are equivalent: -</p> - -<pre> -ok := ch <- 3 -if ok { print("sent") } else { print("not sent") } - -if ch <- 3 { print("sent") } else { print("not sent") } -</pre> - -<p> -In other words, if the program tests the value of a send operation, -the send is non-blocking and the value of the expression is the -success of the operation. If the program does not test the value, -the operation blocks until it succeeds. -</p> -<p> -The receive operation uses the prefix unary operator "<-". -The value of the expression is the value received, whose type -is the element type of the channel. -</p> -<pre> -<-ch -</pre> +<h3 id="Receive_operator">Receive operator</h3> <p> -The expression blocks until a value is available, which then can -be assigned to a variable or used like any other expression. -If the receive expression does not save the value, the value is -discarded. +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. </p> <pre> v1 := <-ch v2 = <-ch f(<-ch) -<-strobe // wait until clock pulse +<-strobe // wait until clock pulse and discard received value </pre> +<!-- + TODO(rsc): Add after a release or two without any x,ok := <-c. + <p> -If a receive expression is used in an assignment or initialization of the form +A receive expression used in an assignment or initialization of the form </p> <pre> @@ -3082,18 +3033,16 @@ var x, ok = <-ch </pre> <p> -the receive operation becomes non-blocking. -If the operation can proceed, the boolean variable -<code>ok</code> will be set to <code>true</code> -and the value stored in <code>x</code>; otherwise -<code>ok</code> is set -to <code>false</code> and <code>x</code> is set to the -zero value for its type (§<a href="#The_zero_value">The zero value</a>). +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> -Except in a communications clause of a <a href="#Select_statements">select statement</a>, -sending or receiving from a <code>nil</code> channel causes a +Receiving from a <code>nil</code> channel causes a <a href="#Run_time_panics">run-time panic</a>. </p> @@ -3104,6 +3053,7 @@ need to be presented regarding send, receive, select, and goroutines.</span> </p> ---> + <h3 id="Method_expressions">Method expressions</h3> <p> @@ -3128,8 +3078,8 @@ Consider a struct type <code>T</code> with two methods, type T struct { a int } -func (tv T) Mv(a int) int { return 0 } // value receiver -func (tp *T) Mp(f float) float { return 1 } // pointer receiver +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> @@ -3174,7 +3124,7 @@ yields a function value representing <code>Mp</code> with signature </p> <pre> -func(tp *T, f float) float +func(tp *T, f float32) float32 </pre> <p> @@ -3422,14 +3372,14 @@ 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>cmplx</code></a>. +<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Γ = cmplx(0, Γ) +const iΓ = complex(0, Γ) </pre> <p> @@ -3525,7 +3475,7 @@ Statement = FallthroughStmt | Block | IfStmt | SwitchStmt | SelectStmt | ForStmt | DeferStmt . -SimpleStmt = EmptyStmt | ExpressionStmt | IncDecStmt | Assignment | ShortVarDecl . +SimpleStmt = EmptyStmt | ExpressionStmt | SendStmt | IncDecStmt | Assignment | ShortVarDecl . </pre> @@ -3553,14 +3503,14 @@ Label = identifier . </pre> <pre> -Error: log.Crash("error encountered") +Error: log.Panic("error encountered") </pre> <h3 id="Expression_statements">Expression statements</h3> <p> -Function calls, method calls, and channel operations +Function calls, method calls, and receive operations can appear in statement context. </p> @@ -3570,11 +3520,44 @@ ExpressionStmt = Expression . </pre> <pre> -f(x+y) +h(x+y) +f.Close() <-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. +</p> + +<pre> +ch <- 3 +</pre> + +<p> +Sending to a <code>nil</code> channel causes a +<a href="#Run_time_panics">run-time panic</a>. +</p> + + <h3 id="IncDec_statements">IncDec statements</h3> <p> @@ -3680,8 +3663,8 @@ 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>float</code>, -<code>complex</code> or <code>string</code> +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> @@ -3847,9 +3830,9 @@ case nil: printString("x is nil") case int: printInt(i) // i is an int -case float: - printFloat(i) // i is a float -case func(int) float: +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{} @@ -3868,9 +3851,9 @@ 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_float := v.(float); is_float { - printFloat(i) // i is a float -} else if i, is_func := v.(func(int) float); is_func { +} 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) @@ -4093,15 +4076,19 @@ cases all referring to communication operations. <pre class="ebnf"> SelectStmt = "select" "{" { CommClause } "}" . CommClause = CommCase ":" { Statement ";" } . -CommCase = "case" ( SendExpr | RecvExpr) | "default" . -SendExpr = Expression "<-" Expression . -RecvExpr = [ Expression ( "=" | ":=" ) ] "<-" Expression . +CommCase = "case" ( SendStmt | RecvStmt ) | "default" . +RecvStmt = [ Expression ( "=" | ":=" ) ] RecvExpr . +RecvExpr = Expression . </pre> +<!-- TODO(rsc): +RecvStmt = [ Expression [ "," Expression ] ( "=" | ":=" ) ] RecvExpr . +--> <p> -For all the send and receive expressions in the "select" +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 expressions. +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 @@ -4126,6 +4113,7 @@ in the "select" statement. If multiple cases can proceed, a pseudo-random fair choice is made to decide which single communication will execute. <p> +<!-- TODO(rsc): s/variable/& or &s/ --> The receive case may declare a new variable using a <a href="#Short_variable_declarations">short variable declaration</a>. </p> @@ -4138,6 +4126,14 @@ case i1 = <-c1: print("received ", i1, " from c1\n") case c2 <- i2: print("sent ", i2, " to c2\n") +<!-- TODO(rsc): add , c3 to channel list above too +case i3, ok := <-c3: + if ok { + print("received ", i3, " from c3\n") + } else { + print("c3 is closed\n") + } +--> default: print("no communication\n") } @@ -4189,7 +4185,7 @@ func simple_f() int { return 2 } -func complex_f1() (re float, im float) { +func complex_f1() (re float64, im float64) { return -7.0, -4.0 } </pre> @@ -4201,7 +4197,7 @@ func complex_f1() (re float, im float) { "return" statement listing these variables, at which point the rules of the previous case apply. <pre> -func complex_f2() (re float, im float) { +func complex_f2() (re float64, im float64) { return complex_f1() } </pre> @@ -4212,7 +4208,7 @@ func complex_f2() (re float, im float) { and the function may assign values to them as necessary. The "return" statement returns the values of these variables. <pre> -func complex_f3() (re float, im float) { +func complex_f3() (re float64, im float64) { re = 7.0 im = 4.0 return @@ -4391,15 +4387,21 @@ BuiltinCall = identifier "(" [ BuiltinArgs [ "," ] ] ")" . BuiltinArgs = Type [ "," ExpressionList ] | ExpressionList . </pre> +<!-- TODO(rsc): s/.and.closed//g --> <h3 id="Close_and_closed">Close and closed</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; -values sent to a closed channel are ignored. +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. + +<!-- TODO(rsc): delete next sentence, replace with + The multi-valued <a href="#Receive_operator">receive operation</a> + returns a received value along with an indication of whether the channel is closed. +--> After at least one such zero value has been received, <code>closed(c)</code> returns true. </p> @@ -4474,7 +4476,7 @@ For instance </p> <pre> -type S struct { a int; b float } +type S struct { a int; b float64 } new(S) </pre> @@ -4593,29 +4595,28 @@ n3 := copy(b, "Hello, World!") // n3 == 5, b == []byte("Hello") <p> Three functions assemble and disassemble complex numbers. -The built-in function <code>cmplx</code> constructs a complex +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"> -cmplx(realPart, imaginaryPart floatT) complexT +complex(realPart, imaginaryPart floatT) complexT real(complexT) floatT imag(complexT) floatT </pre> <p> The type of the arguments and return value correspond. -For <code>cmplx</code>, the two arguments must be of the same +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>complex</code> for <code>float</code>, <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>cmplx(real(z),</code> <code>imag(z))</code>. +<code>z</code> <code>==</code> <code>complex(real(z),</code> <code>imag(z))</code>. </p> <p> @@ -4624,12 +4625,12 @@ value is a constant. </p> <pre> -var a = cmplx(2, -2) // has type complex -var b = cmplx(1.0, -1.4) // has type complex -x := float32(math.Cos(math.Pi/2)) -var c64 = cmplx(5, -x) // has type complex64 -var im = imag(b) // has type float -var rl = real(c64) // type float32 +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> @@ -4984,7 +4985,7 @@ After </p> <pre> -type T struct { i int; f float; next *T } +type T struct { i int; f float64; next *T } t := new(T) </pre> diff --git a/doc/go_tutorial.html b/doc/go_tutorial.html index 11e9b4ad7..ece22036a 100644 --- a/doc/go_tutorial.html +++ b/doc/go_tutorial.html @@ -238,14 +238,19 @@ started; for instance, <code>os.Args</code> is a slice used by the <p> <h2>An Interlude about Types</h2> <p> -Go has some familiar types such as <code>int</code> and <code>float</code>, which represent +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, +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 @@ -452,14 +457,15 @@ language specification but here are some illustrative examples: 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 float + 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 + 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 <code>ints</code> and <code>floats</code>, plus a few other -simple cases. There are no automatic numeric conversions of any kind in Go, +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> @@ -538,9 +544,9 @@ We can use the factory to construct some familiar, exported variables of type <c <p> <pre> <!-- progs/file.go /var/ /^.$/ --> 24 var ( -25 Stdin = newFile(0, "/dev/stdin") -26 Stdout = newFile(1, "/dev/stdout") -27 Stderr = newFile(2, "/dev/stderr") +25 Stdin = newFile(syscall.Stdin, "/dev/stdin") +26 Stdout = newFile(syscall.Stdout, "/dev/stdout") +27 Stderr = newFile(syscall.Stderr, "/dev/stderr") 28 ) </pre> <p> @@ -663,7 +669,7 @@ 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: +Now we can compile and run the program. On Unix, this would be the result: <p> <pre> $ 6g file.go # compile file package diff --git a/doc/go_tutorial.txt b/doc/go_tutorial.txt index 9c08bd278..5eea3c980 100644 --- a/doc/go_tutorial.txt +++ b/doc/go_tutorial.txt @@ -189,14 +189,19 @@ started; for instance, "os.Args" is a slice used by the An Interlude about Types ---- -Go has some familiar types such as "int" and "float", which represent +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, +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 @@ -362,13 +367,14 @@ language specification but here are some illustrative examples: 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 float + 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 + 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 "ints" and "floats", plus a few other -simple cases. There are no automatic numeric conversions of any kind in Go, +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. @@ -482,7 +488,7 @@ 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: +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 diff --git a/doc/htmlgen.go b/doc/htmlgen.go index 4bed9ed73..5d0bad8b5 100644 --- a/doc/htmlgen.go +++ b/doc/htmlgen.go @@ -50,7 +50,7 @@ func read() { break } if err != nil { - log.Exit(err) + log.Fatal(err) } n := len(lines) lines = lines[0 : n+1] diff --git a/doc/install.html b/doc/install.html index 92b099fe8..5917da964 100644 --- a/doc/install.html +++ b/doc/install.html @@ -45,11 +45,10 @@ architectures. </dt> <dd> Incomplete. - It only supports Linux binaries, the optimizer is not enabled, - and floating point is performed entirely in software. + It only supports Linux binaries, the optimizer is incomplete, + and floating point uses the VFP unit. However, all tests pass. - Work on the optimizer and use of the VFP hardware - floating point unit is underway. + Work on the optimizer is continuing. Tested against a Nexus One. </dd> </dl> diff --git a/doc/progs/file.go b/doc/progs/file.go index d3fb5ae9e..df3a3cf71 100644 --- a/doc/progs/file.go +++ b/doc/progs/file.go @@ -22,9 +22,9 @@ func newFile(fd int, name string) *File { } var ( - Stdin = newFile(0, "/dev/stdin") - Stdout = newFile(1, "/dev/stdout") - Stderr = newFile(2, "/dev/stderr") + Stdin = newFile(syscall.Stdin, "/dev/stdin") + Stdout = newFile(syscall.Stdout, "/dev/stdout") + Stderr = newFile(syscall.Stderr, "/dev/stderr") ) func Open(name string, mode int, perm uint32) (file *File, err os.Error) { diff --git a/doc/progs/run b/doc/progs/run index 29f1f8152..241e65dfa 100755 --- a/doc/progs/run +++ b/doc/progs/run @@ -29,9 +29,8 @@ for i in \ sieve.go \ sieve1.go \ server1.go \ + strings.go \ ; do - BASE=$(basename $i .go) - $GC $i done @@ -58,6 +57,7 @@ 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 diff --git a/doc/progs/sort.go b/doc/progs/sort.go index 6738860d9..79e7f563e 100644 --- a/doc/progs/sort.go +++ b/doc/progs/sort.go @@ -37,11 +37,11 @@ func (p IntArray) Less(i, j int) bool { return p[i] < p[j] } func (p IntArray) Swap(i, j int) { p[i], p[j] = p[j], p[i] } -type FloatArray []float +type Float64Array []float64 -func (p FloatArray) Len() int { return len(p) } -func (p FloatArray) Less(i, j int) bool { return p[i] < p[j] } -func (p FloatArray) Swap(i, j int) { p[i], p[j] = p[j], p[i] } +func (p Float64Array) Len() int { return len(p) } +func (p Float64Array) Less(i, j int) bool { return p[i] < p[j] } +func (p Float64Array) Swap(i, j int) { p[i], p[j] = p[j], p[i] } type StringArray []string @@ -54,10 +54,10 @@ func (p StringArray) Swap(i, j int) { p[i], p[j] = p[j], p[i] } // Convenience wrappers for common cases func SortInts(a []int) { Sort(IntArray(a)) } -func SortFloats(a []float) { Sort(FloatArray(a)) } +func SortFloat64s(a []float64) { Sort(Float64Array(a)) } func SortStrings(a []string) { Sort(StringArray(a)) } func IntsAreSorted(a []int) bool { return IsSorted(IntArray(a)) } -func FloatsAreSorted(a []float) bool { return IsSorted(FloatArray(a)) } +func Float64sAreSorted(a []float64) bool { return IsSorted(Float64Array(a)) } func StringsAreSorted(a []string) bool { return IsSorted(StringArray(a)) } diff --git a/doc/progs/strings.go b/doc/progs/strings.go index 0ec25f8e8..2cdb6101a 100644 --- a/doc/progs/strings.go +++ b/doc/progs/strings.go @@ -4,7 +4,6 @@ package main -import "fmt" import "os" func main() { |