From 04b08da9af0c450d645ab7389d1467308cfc2db8 Mon Sep 17 00:00:00 2001
From: Michael Stapelberg
-To build cgo packages, just use "
+To build cgo packages, just use "
go build
" or
-"go install
+"go install
" as usual. The go tool recognizes the special "C"
import and automatically
uses cgo for those files.
For a simple, idiomatic example of a cgo-based package, see Russ Cox's gosqlite. -Also, the Go Project Dashboard lists several other -cgo packages. +Also, the Go Community Wiki +lists many packages, some of which use cgo.
diff --git a/doc/articles/concurrency_patterns.html b/doc/articles/concurrency_patterns.html
index 63c8cd59e..62168b840 100644
--- a/doc/articles/concurrency_patterns.html
+++ b/doc/articles/concurrency_patterns.html
@@ -17,7 +17,7 @@ and launching a goroutine that sleeps before sending on the channel:
We can then use a select
statement to receive from either
ch
or timeout
. If nothing arrives on ch
after one second, the timeout case is selected and the attempt to read from
-ch
is abandoned.
-This problem is a textbook of example of what is known as a
+This problem is a textbook example of what is known as a
race condition, but
the fix is trivial. We just make sure to buffer the channel ch
(by
adding the buffer length as the second argument to make),
diff --git a/doc/articles/error_handling.html b/doc/articles/error_handling.html
index 8f4fffb48..6ba05ac1d 100644
--- a/doc/articles/error_handling.html
+++ b/doc/articles/error_handling.html
@@ -137,7 +137,7 @@ messages:
(This is a slightly simplified version of some -actual code +actual code from the Camlistore project.)
diff --git a/doc/articles/go_command.html b/doc/articles/go_command.html index 1e9e70fd8..fddca41e2 100644 --- a/doc/articles/go_command.html +++ b/doc/articles/go_command.html @@ -48,9 +48,9 @@ had to be installed in certain places, under certain names, using certain build tools, in order to be used. That's understandable: that's the way it works in most other languages. Over the last few years we consistently reminded people about thegoinstall
command
-(now replaced by go get
)
+(now replaced by go get
)
and its conventions: first, that the import path is derived in a known way from
-the URL of the source code; second, that that the place to store the sources in
+the URL of the source code; second, that the place to store the sources in
the local file system is derived in a known way from the import path; third,
that each directory in a source tree corresponds to a single package; and
fourth, that the package is built using only information in the source code.
diff --git a/doc/articles/godoc_documenting_go_code.html b/doc/articles/godoc_documenting_go_code.html
index ca66076ad..18a3ee953 100644
--- a/doc/articles/godoc_documenting_go_code.html
+++ b/doc/articles/godoc_documenting_go_code.html
@@ -65,8 +65,8 @@ package's brief description:
{{code "/src/pkg/sort/sort.go" `/Package sort provides/` `/package sort/`}}
-They can also be detailed like the gob package's
-overview. That package uses another convention for packages
+They can also be detailed like the gob
+package's overview. That package uses another convention for packages
that need large amounts of introductory documentation: the package comment is
placed in its own file, doc.go, which
contains only those comments and a package clause.
@@ -80,10 +80,10 @@ sentence will appear in godoc's package list.
Comments that are not adjacent to a top-level declaration are omitted from
godoc's output, with one notable exception. Top-level comments that begin with
-the word "BUG(who)”
are recognized as known bugs, and included in
-the "Bugs” section of the package documentation. The "who” part should be the
+the word "BUG(who)"
are recognized as known bugs, and included in
+the "Bugs" section of the package documentation. The "who" part should be the
user name of someone who could provide more information. For example, this is a
-known issue from the bytes package:
+known issue from the bytes
package:
@@ -93,7 +93,7 @@ known issue from the bytes package:Godoc treats executable commands somewhat differently. Instead of inspecting the command source code, it looks for a Go source file belonging to the special -package "documentation”. The comment on the "package documentation” clause is +package "documentation". The comment on the "package documentation" clause is used as the command's documentation. For example, see the godoc documentation and its corresponding doc.go file. @@ -137,3 +137,9 @@ indexing via the
+ +-path
flag or just by running"godoc ."godoc documentation for more details.
+Godoc recognizes example functions written according to the +
diff --git a/doc/articles/image_package.html b/doc/articles/image_package.html index a9d2f3581..ebe92a1ca 100644 --- a/doc/articles/image_package.html +++ b/doc/articles/image_package.html @@ -45,7 +45,7 @@ classic algebra: dstr, dstg, dstb, dsta := dst.RGBA() srcr, srcg, srcb, srca := src.RGBA() _, _, _, m := mask.RGBA() -const M = 1<<16 - 1 +const M = 1<<16 - 1 // The resultant red value is a blend of dstr and srcr, and ranges in [0, M]. // The calculation for green, blue and alpha is similar. dstr = (dstr*(M-m) + srcr*m) / M @@ -130,7 +130,7 @@ much easier to type. Atesting
package's naming +conventions and presents them appropriately. +Rectangle
is inclusive at the top-left and exclusive at the bottom-right. For aPoint p
and aRectangle r
,p.In(r)
if and only if -r.Min.X <= p.X && p.X < r.Max.X
, and similarly forY
. This is analagous to how +r.Min.X <= p.X && p.X < r.Max.X
, and similarly forY
. This is analagous to how a slices[i0:i1]
is inclusive at the low end and exclusive at the high end. (Unlike arrays and slices, aRectangle
often has a non-zero origin.) @@ -193,8 +193,8 @@ way to iterate over anImage
m's pixels looks like:b := m.Bounds() -for y := b.Min.Y; y < b.Max.Y; y++ { - for x := b.Min.X; y < b.Max.X; x++ { +for y := b.Min.Y; y < b.Max.Y; y++ { + for x := b.Min.X; x < b.Max.X; x++ { doStuffWith(m.At(x, y)) } } diff --git a/doc/articles/json_and_go.html b/doc/articles/json_and_go.html index af7776c0a..8c4ef33a4 100644 --- a/doc/articles/json_and_go.html +++ b/doc/articles/json_and_go.html @@ -43,7 +43,7 @@ and an instance ofMessage
{{code "/doc/progs/json1.go" `/m :=/`}}-we can marshal a JSON-encoded version of m using
{{code "/doc/progs/json1.go" `/b, err :=/`}} @@ -82,8 +82,8 @@ isjson.Marshal
: +we can marshal a JSON-encoded version ofm
usingjson.Marshal
:nil
).The json package only accesses the exported fields of struct types (those that -begin with an uppercase letter). Therefore only the the exported fields of a -struct will be present in the JSON output. +begin with an uppercase letter). Therefore only the exported fields of a struct +will be present in the JSON output.
@@ -130,7 +130,7 @@ preference):
"Foo"
(see the
+An exported field with a tag of `json:"Foo"`
(see the
Go spec for more on struct tags),
Unmarshal
will decode only the fields that it can find in the
-destination type. In this case, only the Name field of m will be populated,
-and the Food field will be ignored. This behavior is particularly useful when
-you wish to pick only a few specific fields out of a large JSON blob. It also
-means that any unexported fields in the destination struct will be unaffected
-by Unmarshal
.
+destination type. In this case, only the Name
field of m will be
+populated, and the Food
field will be ignored. This behavior is
+particularly useful when you wish to pick only a few specific fields out of a
+large JSON blob. It also means that any unexported fields in the destination
+struct will be unaffected by Unmarshal
.
@@ -163,7 +163,7 @@ But what if you don't know the structure of your JSON data beforehand?
-Generic JSON with interface{}
+Generic JSON with interface{}
@@ -190,11 +190,12 @@ Or, if the underlying type is unknown, a type switch determines the type: {{code "/doc/progs/json2.go" `/switch v/` `/STOP/`}} - +
The json package uses map[string]interface{}
and
[]interface{}
values to store arbitrary JSON objects and arrays;
it will happily unmarshal any valid JSON blob into a plain
interface{}
value. The default concrete Go types are:
+
float64
variable x
, not an
interface value, to reflect.TypeOf
. But it's there; as
-godoc reports, the signature of
+godoc reports, the signature of
reflect.TypeOf
includes an empty interface:
diff --git a/doc/articles/race_detector.html b/doc/articles/race_detector.html
new file mode 100644
index 000000000..400d96b19
--- /dev/null
+++ b/doc/articles/race_detector.html
@@ -0,0 +1,369 @@
+
+
++Data races are one of the most common and hardest to debug types of bugs in concurrent systems. A data race occurs when two goroutines access the same variable concurrently and at least one of the accesses is a write. See the The Go Memory Model for details. +
+ ++Here is an example of a data race that can lead to crashes and memory corruption: +
+ ++func main() { + c := make(chan bool) + m := make(map[string]string) + go func() { + m["1"] = "a" // First conflicting access. + c <- true + }() + m["2"] = "b" // Second conflicting access. + <-c + for k, v := range m { + fmt.Println(k, v) + } +} ++ +
+Fortunately, Go includes a built-in data race detector. To use it, add the -race
flag to the go command:
+
+$ go test -race mypkg // to test the package +$ go run -race mysrc.go // to run the source file +$ go build -race mycmd // to build the command +$ go install -race mypkg // to install the package ++ +
+When the race detector finds a data race in the program, it prints a report. The report contains stack traces for conflicting accesses, as well as stacks where the involved goroutines were created. For example: +
+ ++WARNING: DATA RACE +Read by goroutine 185: + net.(*pollServer).AddFD() + src/pkg/net/fd_unix.go:89 +0x398 + net.(*pollServer).WaitWrite() + src/pkg/net/fd_unix.go:247 +0x45 + net.(*netFD).Write() + src/pkg/net/fd_unix.go:540 +0x4d4 + net.(*conn).Write() + src/pkg/net/net.go:129 +0x101 + net.func·060() + src/pkg/net/timeout_test.go:603 +0xaf + +Previous write by goroutine 184: + net.setWriteDeadline() + src/pkg/net/sockopt_posix.go:135 +0xdf + net.setDeadline() + src/pkg/net/sockopt_posix.go:144 +0x9c + net.(*conn).SetDeadline() + src/pkg/net/net.go:161 +0xe3 + net.func·061() + src/pkg/net/timeout_test.go:616 +0x3ed + +Goroutine 185 (running) created at: + net.func·061() + src/pkg/net/timeout_test.go:609 +0x288 + +Goroutine 184 (running) created at: + net.TestProlongTimeout() + src/pkg/net/timeout_test.go:618 +0x298 + testing.tRunner() + src/pkg/testing/testing.go:301 +0xe8 ++ +
+The GORACE
environment variable sets race detector options. The format is:
+
+GORACE="option1=val1 option2=val2" ++ +
+The options are: +
+ +log_path
(default stderr
): The race detector writes
+its report to a file named log_path.pid. The special names stdout
+and stderr
cause reports to be written to standard output and
+standard error, respectively.
+exitcode
(default 66
): The exit status to use when
+exiting after a detected race.
+strip_path_prefix
(default ""
): Strip this prefix
+from all reported file paths, to make reports more concise.
+history_size
(default 1
): The per-goroutine memory
+access history is 32K * 2**history_size elements
. Increasing this
+value can avoid a "failed to restore the stack" error in reports, but at the
+cost of increased memory usage.
++Example: +
+ ++$ GORACE="log_path=/tmp/race/report strip_path_prefix=/my/go/sources/" go test -race ++ +
+When you build with -race
flag, go command defines additional
+build tag race
.
+You can use it to exclude some code/tests under the race detector. For example:
+
+// +build !race + +package foo + +// The test contains a data race. See issue 123. +func TestFoo(t *testing.T) { + // ... +} + +// The test fails under the race detector due to timeouts. +func TestBar(t *testing.T) { + // ... +} + +// The test takes too long under the race detector. +func TestBaz(t *testing.T) { + // ... +} ++ +
+To start, run your tests using the race detector (go test -race
).
+The race detector only finds races that happen at runtime, so it can't find
+races in code paths that are not executed. If your tests have incomplete coverage,
+you may find more races by running a binary built with -race
under a realistic
+workload.
+
+Here are some typical data races. All of them can be detected with the race detector. +
+ ++func main() { + var wg sync.WaitGroup + wg.Add(5) + for i := 0; i < 5; i++ { + go func() { + fmt.Println(i) // Not the 'i' you are looking for. + wg.Done() + }() + } + wg.Wait() +} ++ +
+The variable i
in the function literal is the same variable used by the loop, so
+the read in the goroutine races with the loop increment. (This program typically
+prints 55555, not 01234.) The program can be fixed by making a copy of the
+variable:
+
+func main() { + var wg sync.WaitGroup + wg.Add(5) + for i := 0; i < 5; i++ { + go func(j int) { + fmt.Println(j) // Good. Read local copy of the loop counter. + wg.Done() + }(i) + } + wg.Wait() +} ++ +
+// ParallelWrite writes data to file1 and file2, returns the errors. +func ParallelWrite(data []byte) chan error { + res := make(chan error, 2) + f1, err := os.Create("file1") + if err != nil { + res <- err + } else { + go func() { + // This err is shared with the main goroutine, + // so the write races with the write below. + _, err = f1.Write(data) + res <- err + f1.Close() + }() + } + f2, err := os.Create("file2") // The second conflicting write to err. + if err != nil { + res <- err + } else { + go func() { + _, err = f2.Write(data) + res <- err + f2.Close() + }() + } + return res +} ++ +
+The fix is to introduce new variables in the goroutines (note :=
):
+
+ ... + _, err := f1.Write(data) + ... + _, err := f2.Write(data) + ... ++ +
+If the following code is called from several goroutines, it leads to bad races on the service
map.
+Concurrent reads and writes of a map are not safe:
+
+var service map[string]net.Addr + +func RegisterService(name string, addr net.Addr) { + service[name] = addr +} + +func LookupService(name string) net.Addr { + return service[name] +} ++ +
+To make the code safe, protect the accesses with a mutex: +
+ ++var ( + service map[string]net.Addr + serviceMu sync.Mutex +) + +func RegisterService(name string, addr net.Addr) { + serviceMu.Lock() + defer serviceMu.Unlock() + service[name] = addr +} + +func LookupService(name string) net.Addr { + serviceMu.Lock() + defer serviceMu.Unlock() + return service[name] +} ++ +
+Data races can happen on variables of primitive types as well (bool
, int
, int64
, etc.), like in the following example:
+
+type Watchdog struct{ last int64 } + +func (w *Watchdog) KeepAlive() { + w.last = time.Now().UnixNano() // First conflicting access. +} + +func (w *Watchdog) Start() { + go func() { + for { + time.Sleep(time.Second) + // Second conflicting access. + if w.last < time.Now().Add(-10*time.Second).UnixNano() { + fmt.Println("No keepalives for 10 seconds. Dying.") + os.Exit(1) + } + } + }() +} ++ +
+Even such “innocent” data races can lead to hard to debug problems caused by (1) non-atomicity of the memory accesses, (2) interference with compiler optimizations and (3) processor memory access reordering issues. +
+ +
+A typical fix for this race is to use a channel or a mutex.
+To preserve the lock-free behavior, one can also use the sync/atomic
package.
+
+type Watchdog struct{ last int64 } + +func (w *Watchdog) KeepAlive() { + atomic.StoreInt64(&w.last, time.Now().UnixNano()) +} + +func (w *Watchdog) Start() { + go func() { + for { + time.Sleep(time.Second) + if atomic.LoadInt64(&w.last) < time.Now().Add(-10*time.Second).UnixNano() { + fmt.Println("No keepalives for 10 seconds. Dying.") + os.Exit(1) + } + } + }() +} ++ +
+The race detector runs on darwin/amd64
, linux/amd64
, and windows/amd64
.
+
+The cost of race detection varies by program, but for a typical program, memory +usage may increase by 5-10x and execution time by 2-20x. +
diff --git a/doc/articles/slices_usage_and_internals.html b/doc/articles/slices_usage_and_internals.html index 810b0a41f..7eb751b45 100644 --- a/doc/articles/slices_usage_and_internals.html +++ b/doc/articles/slices_usage_and_internals.html @@ -243,7 +243,7 @@ slice itself) of a re-slice modifies the elements of the original slice: d := []byte{'r', 'o', 'a', 'd'} e := d[2:] // e == []byte{'a', 'd'} -e[1] == 'm' +e[1] = 'm' // e == []byte{'a', 'm'} // d == []byte{'r', 'o', 'a', 'm'} diff --git a/doc/articles/wiki/get.go b/doc/articles/wiki/get.go index c6e9bf28b..b3e464b34 100644 --- a/doc/articles/wiki/get.go +++ b/doc/articles/wiki/get.go @@ -13,11 +13,13 @@ import ( "net/http" "os" "strings" + "time" ) var ( post = flag.String("post", "", "urlencoded form data to POST") addr = flag.Bool("addr", false, "find open address and print to stdout") + wait = flag.Duration("wait_for_port", 0, "if non-zero, the amount of time to wait for the address to become available") ) func main() { @@ -37,11 +39,18 @@ func main() { } var r *http.Response var err error - if *post != "" { - b := strings.NewReader(*post) - r, err = http.Post(url, "application/x-www-form-urlencoded", b) - } else { - r, err = http.Get(url) + loopUntil := time.Now().Add(*wait) + for { + 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 || *wait == 0 || time.Now().After(loopUntil) { + break + } + time.Sleep(100 * time.Millisecond) } if err != nil { log.Fatal(err) diff --git a/doc/articles/wiki/index.html b/doc/articles/wiki/index.html index 6c45d7178..ea3507f4d 100644 --- a/doc/articles/wiki/index.html +++ b/doc/articles/wiki/index.html @@ -46,7 +46,7 @@ $ cd gowiki
-Create a file named wiki.go
, open it in your favorite editor, and
+Create a file named wiki.go
, open it in your favorite editor, and
add the following lines:
-We import the fmt
and ioutil
packages from the Go
-standard library. Later, as we implement additional functionality, we will
+We import the fmt
and ioutil
packages from the Go
+standard library. Later, as we implement additional functionality, we will
add more packages to this import
declaration.
-The type []byte
means "a byte
slice".
+The type []byte
means "a byte
slice".
(See Slices: usage and
internals for more on slices.)
The Body
element is a []byte
rather than
@@ -86,8 +86,8 @@ libraries we will use, as you'll see below.
-The Page
struct describes how page data will be stored in memory.
-But what about persistent storage? We can address that by creating a
+The Page
struct describes how page data will be stored in memory.
+But what about persistent storage? We can address that by creating a
save
method on Page
:
This method's signature reads: "This is a method named save
that
takes as its receiver p
, a pointer to Page
. It takes
-no parameters, and returns a value of type error
."
+no parameters, and returns a value of type error
."
-This method will save the Page
's Body
to a text
+This method will save the Page
's Body
to a text
file. For simplicity, we will use the Title
as the file name.
WriteFile
(a standard library function
that writes a byte slice to a file). The save
method returns the
error value, to let the application handle it should anything go wrong while
writing the file. If all goes well, Page.save()
will return
-nil
(the zero-value for pointers, interfaces, and some other
+nil
(the zero-value for pointers, interfaces, and some other
types).
-The octal integer constant 0600
, passed as the third parameter to
+The octal integer literal 0600
, passed as the third parameter to
WriteFile
, indicates that the file should be created with
read-write permissions for the current user only. (See the Unix man page
open(2)
for details.)
-We will want to load pages, too: +In addition to saving pages, we will want to load pages, too:
{{code "doc/articles/wiki/part1-noerror.go" `/^func loadPage/` `/^}/`}}
The function loadPage
constructs the file name from
-Title
, reads the file's contents into a new
-Page
, and returns a pointer to that new page
.
+the title parameter, reads the file's contents into a new
+variable body
, and returns two values: a pointer to a
+Page
literal constructed with the proper title and body
+values and nil
for the error value.
-Functions can return multiple values. The standard library function
-io.ReadFile
returns []byte
and error
.
+Functions can return multiple values. The standard library function
+io.ReadFile
returns []byte
and error
.
In loadPage
, error isn't being handled yet; the "blank identifier"
represented by the underscore (_
) symbol is used to throw away the
-error return value (in essence, assigning the value to nothing).
+error return value (in essence, assigning the value to nothing).
@@ -152,7 +154,7 @@ function to return *Page
and error
.
Callers of this function can now check the second parameter; if it is
nil
then it has successfully loaded a Page. If not, it will be an
-error
that can be handled by the caller (see the
+error
that can be handled by the caller (see the
language specification for details).
-You can compile and run the program like this: +You can compile and run the program like this:
@@ -182,7 +184,7 @@ This is a sample page.
-(If you're using Windows you must type "wiki
" without the
+(If you're using Windows you must type "wiki
" without the
"./
" to run the program.)
-The main
function begins with a call to
-http.HandleFunc
, which tells the http
package to
-handle all requests to the web root ("/"
) with
-handler
.
+The main
function begins with a call to
+http.HandleFunc
, which tells the http
package to
+handle all requests to the web root ("/"
) with
+handler
.
@@ -219,20 +221,20 @@ its arguments.
-An http.ResponseWriter
value assembles the HTTP server's response; by writing
+An http.ResponseWriter
value assembles the HTTP server's response; by writing
to it, we send data to the HTTP client.
An http.Request
is a data structure that represents the client
-HTTP request. The string r.URL.Path
is the path component
-of the request URL. The trailing [1:]
means
-"create a sub-slice of Path
from the 1st character to the end."
+HTTP request. r.URL.Path
is the path component
+of the request URL. The trailing [1:]
means
+"create a sub-slice of Path
from the 1st character to the end."
This drops the leading "/" from the path name.
-If you run this program and access the URL: +If you run this program and access the URL:
http://localhost:8080/monkeys
@@ -249,13 +251,14 @@ To use the net/http
package, it must be imported:
import ( "fmt" - "net/http" "io/ioutil" + "net/http" )
-Let's create a handler to view a wiki page:
+Let's create a handler, viewHandler
that will allow users to
+view a wiki page. It will handle URLs prefixed with "/view/".
First, this function extracts the page title from r.URL.Path
,
-the path component of the request URL. The global constant
+the path component of the request URL. The global constant
lenPath
is the length of the leading "/view/"
component of the request path.
-The Path
is re-sliced with [lenPath:]
to drop the
-first 6 characters of the string. This is because the path will invariably
-begin with "/view/"
, which is not part of the page title.
+The Path
is re-sliced with [lenPath:]
to drop the
+first 6 characters of the string. This is because the path will invariably
+begin with "/view/"
, which is not part of the page's title.
-The function then loads the page data, formats the page with a string of simple
-HTML, and writes it to w
, the http.ResponseWriter
.
+The function then loads the page data, formats the page with a string of simple
+HTML, and writes it to w
, the http.ResponseWriter
.
-Again, note the use of _
to ignore the error
+Again, note the use of _
to ignore the error
return value from loadPage
. This is done here for simplicity
and generally considered bad practice. We will attend to this later.
-To use this handler, we create a main
function that
-initializes http
using the viewHandler
to handle
+To use this handler, we rewrite our main
function to
+initialize http
using the viewHandler
to handle
any requests under the path /view/
.
+(If you're using Windows you must type "wiki
" without the
+"./
" to run the program.)
+
With this web server running, a visit to http://localhost:8080/view/test
@@ -326,14 +334,14 @@ form.
-First, we add them to main()
:
+First, we add them to main()
:
-The function editHandler
loads the page
-(or, if it doesn't exist, create an empty Page
struct),
+The function editHandler
loads the page
+(or, if it doesn't exist, create an empty Page
struct),
and displays an HTML form.
html/template
package@@ -354,20 +362,20 @@ underlying Go code.
-First, we must add html/template
to the list of imports:
+First, we must add html/template
to the list of imports. We
+also won't be using fmt
anymore, so we have to remove that.
import ( "html/template" - "http" "io/ioutil" - "os" + "net/http" )
-Let's create a template file containing the HTML form.
+Let's create a template file containing the HTML form.
Open a new file named edit.html
, and add the following lines:
-The function template.ParseFiles
will read the contents of
-edit.html
and return a *template.Template
.
+The function template.ParseFiles
will read the contents of
+edit.html
and return a *template.Template
.
@@ -405,12 +413,7 @@ HTML.
-Now that we've removed the fmt.Fprintf
statement, we can remove
-"fmt"
from the import
list.
-
-While we're working with templates, let's create a template for our
+Since we're working with templates now, let's create a template for our
viewHandler
called view.html
:
-The handlers are now shorter and simpler.
+If we comment out the registration of our unimplemented save handler in
+main
, we can once again build and test our program.
+Click here to view the code we've written so far.
What if you visit
-/view/APageThatDoesntExist
? The program will crash. This is
-because it ignores the error return value from loadPage
. Instead,
-if the requested Page doesn't exist, it should redirect the client to the edit
-Page so the content may be created:
+/view/APageThatDoesntExist
? You'll see a page containing
+HTML. This is because it ignores the error return value from
+loadPage
and continues to try and fill out the template
+with no data. Instead, if the requested Page doesn't exist, it should
+redirect the client to the edit Page so the content may be created:
-The http.Redirect
function adds an HTTP status code of
+The http.Redirect
function adds an HTTP status code of
http.StatusFound
(302) and a Location
header to the HTTP response.
-The function saveHandler
will handle the form submission.
+The function saveHandler
will handle the submission of forms
+located on the edit pages. After uncommenting the related line in
+main
, let's implement the the handler:
-The page title (provided in the URL) and the form's only field,
-Body
, are stored in a new Page
.
+The page title (provided in the URL) and the form's only field,
+Body
, are stored in a new Page
.
The save()
method is then called to write the data to a file,
and the client is redirected to the /view/
page.
The value returned by FormValue
is of type string
.
-We must convert that value to []byte
before it will fit into
-the Page
struct. We use []byte(body)
to perform
+We must convert that value to []byte
before it will fit into
+the Page
struct. We use []byte(body)
to perform
the conversion.
There are several places in our program where errors are being ignored. This is bad practice, not least because when an error does occur the program will -crash. A better solution is to handle the errors and return an error message -to the user. That way if something does go wrong, the server will continue to -function and the user will be notified. +have unintended behavior. A better solution is to handle the errors and return +an error message to the user. That way if something does go wrong, the server +will function exactly how we want and the user can be notified.
@@ -493,7 +501,7 @@ First, let's handle the errors in renderTemplate
:
{{code "doc/articles/wiki/final-parsetemplate.go" `/^func renderTemplate/` `/^}/`}}
-The http.Error
function sends a specified HTTP response code
+The http.Error
function sends a specified HTTP response code
(in this case "Internal Server Error") and error message.
Already the decision to put this in a separate function is paying off.
saveHandler
:
-{{code "doc/articles/wiki/final-noclosure.go" `/^func saveHandler/` `/^}/`}}
+{{code "doc/articles/wiki/part3-errorhandling.go" `/^func saveHandler/` `/^}/`}}
-Any errors that occur during p.save()
will be reported
+Any errors that occur during p.save()
will be reported
to the user.
-There is an inefficiency in this code: renderTemplate
calls
-ParseFiles
every time a page is rendered.
+There is an inefficiency in this code: renderTemplate
calls
+ParseFiles
every time a page is rendered.
A better approach would be to call ParseFiles
once at program
initialization, parsing all templates into a single *Template
.
Then we can use the
@@ -536,10 +544,11 @@ can't be loaded the only sensible thing to do is exit the program.
-A for
loop is used with a range
statement to iterate
-over an array constant containing the names of the templates we want parsed.
-If we were to add more templates to our program, we would add their names to
-that array.
+The ParseFiles
function takes any number of string arguments that
+identify our template files, and parses those files into templates that are
+named after the base file name. If we were to add more templates to our
+program, we would add their names to the ParseFiles
call's
+arguments.
@@ -571,25 +580,27 @@ Then we can create a global variable to store our validation regexp: {{code "doc/articles/wiki/final-noclosure.go" `/^var titleValidator/`}}
-The function regexp.MustCompile
will parse and compile the
-regular expression, and return a regexp.Regexp
.
+The function regexp.MustCompile
will parse and compile the
+regular expression, and return a regexp.Regexp
.
MustCompile
is distinct from Compile
in that it will
panic if the expression compilation fails, while Compile
returns
-an error
as a second parameter.
+an error
as a second parameter.
-Now, let's write a function that extracts the title string from the request
-URL, and tests it against our TitleValidator
expression:
+Now, let's write a function, getTitle
, that extracts the title
+string from the request URL, and tests it against our
+TitleValidator
expression:
If the title is valid, it will be returned along with a nil
-error value. If the title is invalid, the function will write a
-"404 Not Found" error to the HTTP connection, and return an error to the
-handler.
+error value. If the title is invalid, the function will write a
+"404 Not Found" error to the HTTP connection, and return an error to the
+handler. To create a new error, we have to import the errors
+package.
@@ -604,10 +615,10 @@ Let's put a call to getTitle
in each of the handlers:
Catching the error condition in each handler introduces a lot of repeated code. -What if we could wrap each of the handlers in a function that does this -validation and error checking? Go's -function -literals provide a powerful means of abstracting functionality +What if we could wrap each of the handlers in a function that does this +validation and error checking? Go's +function +literals provide a powerful means of abstracting functionality that can help us here.
@@ -654,19 +665,19 @@ Now we can take the code fromgetTitle
and use it here
The closure returned by makeHandler
is a function that takes
an http.ResponseWriter
and http.Request
(in other
-words, an http.HandlerFunc
).
+words, an http.HandlerFunc
).
The closure extracts the title
from the request path, and
validates it with the TitleValidator
regexp. If the
title
is invalid, an error will be written to the
-ResponseWriter
using the http.NotFound
function.
+ResponseWriter
using the http.NotFound
function.
If the title
is valid, the enclosed handler function
fn
will be called with the ResponseWriter
,
Request
, and title
as arguments.
-Now we can wrap the handler functions with makeHandler
in
-main
, before they are registered with the http
+Now we can wrap the handler functions with makeHandler
in
+main
, before they are registered with the http
package:
Visiting http://localhost:8080/view/ANewPage -should present you with the page edit form. You should then be able to +should present you with the page edit form. You should then be able to enter some text, click 'Save', and be redirected to the newly created page.
@@ -710,11 +721,11 @@ Here are some simple tasks you might want to tackle on your own:tmpl/
and page data in data/
.
-/view/FrontPage
.[PageName]
to <a href="/view/PageName">PageName</a>
.
(hint: you could use regexp.ReplaceAllFunc
to do this)
diff --git a/doc/articles/wiki/part3-errorhandling.go b/doc/articles/wiki/part3-errorhandling.go
new file mode 100644
index 000000000..945aa1e39
--- /dev/null
+++ b/doc/articles/wiki/part3-errorhandling.go
@@ -0,0 +1,75 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "html/template"
+ "io/ioutil"
+ "net/http"
+)
+
+type Page struct {
+ Title string
+ Body []byte
+}
+
+func (p *Page) save() error {
+ filename := p.Title + ".txt"
+ return ioutil.WriteFile(filename, p.Body, 0600)
+}
+
+func loadPage(title string) (*Page, error) {
+ filename := title + ".txt"
+ body, err := ioutil.ReadFile(filename)
+ if err != nil {
+ return nil, err
+ }
+ return &Page{Title: title, Body: body}, nil
+}
+
+const lenPath = len("/view/")
+
+func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
+ t, _ := template.ParseFiles(tmpl + ".html")
+ t.Execute(w, p)
+}
+
+func viewHandler(w http.ResponseWriter, r *http.Request) {
+ title := r.URL.Path[lenPath:]
+ p, err := loadPage(title)
+ if err != nil {
+ http.Redirect(w, r, "/edit/"+title, http.StatusFound)
+ return
+ }
+ renderTemplate(w, "view", p)
+}
+
+func editHandler(w http.ResponseWriter, r *http.Request) {
+ title := r.URL.Path[lenPath:]
+ p, err := loadPage(title)
+ if err != nil {
+ p = &Page{Title: title}
+ }
+ renderTemplate(w, "edit", p)
+}
+
+func saveHandler(w http.ResponseWriter, r *http.Request) {
+ title := r.URL.Path[lenPath:]
+ body := r.FormValue("body")
+ p := &Page{Title: title, Body: []byte(body)}
+ err := p.save()
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ http.Redirect(w, r, "/view/"+title, http.StatusFound)
+}
+
+func main() {
+ http.HandleFunc("/view/", viewHandler)
+ http.HandleFunc("/edit/", editHandler)
+ http.HandleFunc("/save/", saveHandler)
+ http.ListenAndServe(":8080", nil)
+}
diff --git a/doc/articles/wiki/part3.go b/doc/articles/wiki/part3.go
new file mode 100644
index 000000000..7fe4351af
--- /dev/null
+++ b/doc/articles/wiki/part3.go
@@ -0,0 +1,59 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "html/template"
+ "io/ioutil"
+ "net/http"
+)
+
+type Page struct {
+ Title string
+ Body []byte
+}
+
+func (p *Page) save() error {
+ filename := p.Title + ".txt"
+ return ioutil.WriteFile(filename, p.Body, 0600)
+}
+
+func loadPage(title string) (*Page, error) {
+ filename := title + ".txt"
+ body, err := ioutil.ReadFile(filename)
+ if err != nil {
+ return nil, err
+ }
+ return &Page{Title: title, Body: body}, nil
+}
+
+const lenPath = len("/view/")
+
+func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
+ t, _ := template.ParseFiles(tmpl + ".html")
+ t.Execute(w, p)
+}
+
+func viewHandler(w http.ResponseWriter, r *http.Request) {
+ title := r.URL.Path[lenPath:]
+ p, _ := loadPage(title)
+ renderTemplate(w, "view", p)
+}
+
+func editHandler(w http.ResponseWriter, r *http.Request) {
+ title := r.URL.Path[lenPath:]
+ p, err := loadPage(title)
+ if err != nil {
+ p = &Page{Title: title}
+ }
+ renderTemplate(w, "edit", p)
+}
+
+func main() {
+ http.HandleFunc("/view/", viewHandler)
+ http.HandleFunc("/edit/", editHandler)
+ //http.HandleFunc("/save/", saveHandler)
+ http.ListenAndServe(":8080", nil)
+}
diff --git a/doc/articles/wiki/test.bash b/doc/articles/wiki/test.bash
index 5c2cb60dc..02ed1894a 100755
--- a/doc/articles/wiki/test.bash
+++ b/doc/articles/wiki/test.bash
@@ -18,11 +18,10 @@ go build -o final-test.bin final-test.go
(./final-test.bin) &
wiki_pid=$!
-sleep 1
-
-./get.bin http://$addr/edit/Test > test_edit.out
+./get.bin --wait_for_port=5s 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
+./get.bin -post=body=some%20content http://$addr/save/Test > test_save.out
+diff -u test_save.out test_view.good # should be the same as viewing
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
diff --git a/doc/code.html b/doc/code.html
index efbe7eed0..82b211870 100644
--- a/doc/code.html
+++ b/doc/code.html
@@ -10,6 +10,10 @@ introduces the go command, the standard way to fetch,
build, and install Go packages and commands.
++This content is also available as a screencast. +
+
-Run go help test
and see the
+Run go help test
and see the
testing package documentation for more detail.
This convention is the easiest way to make your Go packages available for others to use. -The Go Project Dashboard -is a list of external Go projects including programs and libraries. +The Go Community Wiki +has a list of external Go projects including programs and libraries.
For more information on using remote repositories with the go
command, see
-go help remote
.
+go help remote
.
-The Mercurial Queues extension (mq
) provides a mechanism for
-managing patches on top of a Mercurial repository and is described in detail
-in Chapters
-12
-and 13
-of Mercurial: The Definitive Guide.
-This document explains how to use mq
in conjunction
-with the codereview
Mercurial extension described in the
-instructions for contributing to the Go project.
-It assumes you have read those instructions.
-
-To enable mq
edit either $HOME/.hgrc
(to enable it
-for all of your repositories) or $GOROOT/.hg/hgrc
(to enable it for the
-repository at $GOROOT
) to add:
-[extensions] -mq= -- -
-Since pulling, pushing, updating and committing while mq
patches
-are applied can damage your repository or a remote one, add these lines to
-prevent that case:
-
-[hooks] -# Prevent "hg pull" if MQ patches are applied. -prechangegroup.mq-no-pull = ! hg qtop > /dev/null 2>&1 -# Prevent "hg push" if MQ patches are applied. -preoutgoing.mq-no-push = ! hg qtop > /dev/null 2>&1 -# Prevent "hg update" if MQ patches are applied. -preupdate.mq-no-update = ! hg qtop > /dev/null 2>&1 -- -
-The entire checked-out tree is writable and you can use mq
,
-as documented in Chapter
-12
-of "The Guide",
-to implement your change as a single patch or a series of patches.
-
-
When you are ready to send a change out for review, run
- --$ hg change -- -
from any directory in your Go repository with all of the mq
patches relevant to your
-change applied and then proceed as instructed in contributing
-to the Go project.
-
-The change number reported by hg change
, preceded by a +
,
-can be used as an mq
patch guard to assist in controlling which patches
-are applied as described in Chapter
-13
-of "The Guide".
-For example, the command:
-
-for p in $(hg qapplied); do hg qguard $p +99999; done -- -
-will apply the guard +99999
guard to all currently applied mq
-patches.
-
While you were working, others might have submitted changes
-to the repository and, as explained in contributing
-to the Go project, it is necessary to synchronize your repository using
-hg sync
before sending your change list for review.
-Because hg sync
runs hg pull -u
,
-you should not run hg sync
while mq
patches are
-applied. Instead
-pop all your patches before running hg sync
and reapply them after
-it has completed.
-
-When reapplying the patches, you may need to resolve conflicts -as described in contributing to the Go project. -
- -
-You should have all of the mq
patches relevant to your
-change applied when you run hg mail
.
-
-
mq
patches relevant to your
-change applied when you run hg commit
.
diff --git a/doc/codewalk/codewalk.js b/doc/codewalk/codewalk.js
index f780bc7a5..eb4667ac0 100644
--- a/doc/codewalk/codewalk.js
+++ b/doc/codewalk/codewalk.js
@@ -297,7 +297,7 @@ CodewalkViewer.prototype.updateHeight = function() {
};
jQuery(document).ready(function() {
- var viewer = new CodewalkViewer(jQuery());
+ var viewer = new CodewalkViewer(jQuery('#codewalk-main'));
viewer.selectFirstComment();
viewer.targetCommentLinksAtBlank();
viewer.installEventHandlers();
diff --git a/doc/codewalk/markov.xml b/doc/codewalk/markov.xml
index b7b711783..7f1281817 100644
--- a/doc/codewalk/markov.xml
+++ b/doc/codewalk/markov.xml
@@ -58,7 +58,7 @@ Prefix Map key
this data.
-Chain
struct has two unexported fields (those that
do not begin with an upper case character), and so we write a
NewChain
constructor function that initializes the
diff --git a/doc/codewalk/pig.go b/doc/codewalk/pig.go
index 10963b4e4..941daaed1 100644
--- a/doc/codewalk/pig.go
+++ b/doc/codewalk/pig.go
@@ -23,7 +23,7 @@ type score struct {
// An action transitions stochastically to a resulting score.
type action func(current score) (result score, turnIsOver bool)
-// roll returns the (result, turnIsOver) outcome of simulating a die roll.
+// roll returns the (result, turnIsOver) outcome of simulating a die roll.
// If the roll value is 1, then thisTurn score is abandoned, and the players'
// roles swap. Otherwise, the roll value is added to thisTurn.
func roll(s score) (score, bool) {
diff --git a/doc/contrib.html b/doc/contrib.html
index b4bd47e96..a9f12f93f 100644
--- a/doc/contrib.html
+++ b/doc/contrib.html
@@ -34,9 +34,6 @@ We encourage all Go users to subscribe to
A summary of the changes between Go releases.
-A summary of the changes between weekly snapshots of Go.
-The golang-dev mailing list is for discussing and reviewing code for the Go project.
@@ -91,12 +88,15 @@ are particularly in need of outside help.The golang-nuts mailing list is for general Go discussion.
-A list of external Go projects including programs and libraries.
#go-nuts on irc.freenode.net is the official Go IRC channel.
+The Google+ community for Go enthusiasts.
+The Go project's Google+ page.
diff --git a/doc/contribute.html b/doc/contribute.html index e1f39ae7e..72c936472 100644 --- a/doc/contribute.html +++ b/doc/contribute.html @@ -7,7 +7,7 @@
This document explains how to contribute changes to the Go project.
It assumes you have installed Go using the
-installation instructions and
+installation instructions and
have written and tested your code.
(Note that the gccgo
frontend lives elsewhere;
see Contributing to gccgo.)
@@ -46,24 +46,13 @@ tree to make sure the changes don't break other packages or programs:
cd $GOROOT/src -./all.bash +./all.bash # On Windows, run all.bat
-The final line printed by make all
should be of the form:
+After running for a while, the command should print "ALL TESTS PASSED
".
-N known bugs; 0 unexpected bugs -- -
-The value of N varies over time, but the line must
-say “0 unexpected bugs
” and must not
-add “test output differs
.”
-
@@ -104,41 +93,44 @@ the code review extension disables the standard hg commit
command.
-Mercurial power users: if you prefer to use the Mercurial Queues extension, see -Using Mercurial Queues with Codereview. -
-Edit $GOROOT/.hg/hgrc
to add:
[extensions] -codereview = YOUR_GO_ROOT/lib/codereview/codereview.py +codereview = $GOROOT/lib/codereview/codereview.py [ui] username = Your Name <you@server.dom>-
Replace YOUR_GO_ROOT with the value of $GOROOT
.
-The Mercurial configuration file format does not allow environment variable substitution.
+
The username
information will not be used unless
you are a committer (see below), but Mercurial complains if it is missing.
+After adding the extension, hg help codereview
+will show documentation for its commands. As the codereview extension is only
+enabled for your checkout in $GOROOT
, the remainder of this
+document assumes you are inside $GOROOT
when issuing commands.
+
The code review server uses a Google Account to authenticate.
(If you can use the account to
sign in at google.com,
-you can use it to sign in to the code review server.
+you can use it to sign in to the code review server.)
The email address you use on the Code Review site
will be recorded in the Mercurial change log
and in the CONTRIBUTORS
file.
You can create a Google Account
associated with any address where you receive email.
+If you've enabled the two-step verification feature, don't forget to generate an
+application-specific password and use that when prompted for a password.
@@ -163,6 +155,19 @@ can use that nickname as a shorthand for naming reviewers and the CC list. For example,+rsc
is an alias forrsc@golang.org
. +Switch to the default branch
+ ++Most Go installations use a release branch, but new changes should +only be made to the default branch. (They may be applied later to a release +branch as part of the release process.) +Before making a change, make sure you use the default branch: +
+ ++$ hg update default ++Make a change
@@ -263,6 +268,8 @@ The special sentence “Fixes issue 159.” associates the change with issue 159 in the Go issue tracker. When this change is eventually submitted, the issue tracker will automatically mark the issue as fixed. +(These conventions are described in detail by the +Google Project Hosting Issue Tracker documentation.)
@@ -277,15 +284,37 @@ which
hg change
will print, something like: CL created: http://codereview.appspot.com/99999
-If you need to re-edit the change description,
+If you need to re-edit the change description, or change the files included in the CL,
run hg change 99999
.
-You can see a list of your pending changes by running hg pending
(hg p
for short).
+Alternatively, you can use
+$ hg file 99999 somefile ++ +
+to add somefile
to CL 99999, and
+
+$ hg file -d 99999 somefile ++ +
+to remove somefile
from the CL.
+
+A file may only belong to a single active CL at a time. hg file
+will issue a warning if a file is moved between changes.
+
+Creating or uploading the change uploads a copy of the diff to the code review server,
+but it does not notify anyone about it. To do that, you need to run hg mail
+(see below).
+
To send out a change for review, run hg mail
using the change list number
assigned during hg change
:
Note that -r
and --cc
cannot be spelled --r
or -cc
.
+If your change relates to an open issue, please add a comment to the issue +announcing your proposed fix, including a link to your CL. +
You will probably revise your code in response to the reviewer comments. +
+You will probably revise your code in response to the reviewer comments. When
+you have done this, you can upload your change to the code review server
+without sending a notification by running hg upload
using the change
+list number assigned during hg change
+
+$ hg upload 99999 ++ +
When you have revised the code and are ready for another round of review, run
@@ -433,39 +483,59 @@ The reviewer approves the change by replying with a mail that saysLGTM
: looks good to me.
-
+You can see a list of your pending changes by running hg pending
(hg p
for short).
+
-After the code has been LGTM
'ed, it is time to submit
-it to the Mercurial repository.
-If you are a committer, you can run:
+You can import a CL proposed by someone else into your local Mercurial client
+by using the hg clpatch
command. Running
-$ hg submit 99999 +$ hg clpatch 99999
-This checks the change into the repository.
-The change description will include a link to the code review,
-and the code review will be updated with a link to the change
-in the repository.
+will apply the latest diff for CL 99999 to your working copy. If any of the
+files referenced in CL 99999 have local modifications, clpatch
+will refuse to apply the whole diff. Once applied, CL 99999 will show up in
+the output of hg pending
and others.
-If your local copy of the repository is out of date,
-hg submit
-will refuse the change:
+To revert a CL you have applied locally, use the hg revert
+command. Running
-$ hg submit 99999 -local repository out of date; must sync before submit +$ hg revert @99999+
+will revert any files mentioned on CL 99999 to their original state. This can +be an effective way of reverting one CL revision and applying another. +
+ +
+Once the CL has been submitted, the next time you run hg sync
+it will be removed from your local pending list. Occasionally the pending list
+can get out of sync leaving stale references to closed or abandoned CLs.
+You can use hg change -D 99999
to remove the reference to CL 99999.
+
+After the code has been LGTM
'ed, it is time to submit
+it to the Mercurial repository.
+
If you are not a committer, you cannot submit the change directly.
-Instead, a committer, usually the reviewer who said LGTM
,
+Instead a committer, usually the reviewer who said LGTM
,
will run:
The clpatch
command imports your change 99999 into
-the committer's local Mercurial client, at which point the committer
-can check or test the code more.
-(Anyone can run clpatch
to try a change that
-has been uploaded to the code review server.)
+
The submit
command submits the code. You will be listed as the
author, but the change message will also indicate who the committer was.
Your local client will notice that the change has been submitted
when you next run hg sync
.
+If you are a committer, you can run: +
+ ++$ hg submit 99999 ++ +
+This checks the change into the repository. +The change description will include a link to the code review, +and the code review will be updated with a link to the change +in the repository. +
-
+If your local copy of the repository is out of date,
+hg submit
will refuse the change:
+
+$ hg submit 99999 +local repository out of date; must sync before submit ++ +
Files in the Go repository don't list author names,
both to avoid clutter and to avoid having to keep the lists up to date.
@@ -497,7 +587,7 @@ and perhaps the AUTHORS
file.
The CONTRIBUTORS
file
defines who the Go contributors—the people—are;
-the AUTHORS
file, which defines
+the AUTHORS
file defines
who “The Go Authors”—the copyright holders—are.
The Go developers at Google will update these files when submitting
your first change.
@@ -525,7 +615,12 @@ This rigmarole needs to be done only for your first submission.
Code that you contribute should use the standard copyright header:
-// Copyright 2012 The Go Authors. All rights reserved. +// Copyright 2013 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file.+ +
+Files in the repository are copyright the year they are added. It is not +necessary to update the copyright year on files that you change. +
diff --git a/doc/debugging_with_gdb.html b/doc/debugging_with_gdb.html index b2683913f..b893f931a 100644 --- a/doc/debugging_with_gdb.html +++ b/doc/debugging_with_gdb.html @@ -13,7 +13,7 @@ Besides this overview you might want to consult the
When you compile and link your Go programs with the gc
toolchain
-on Linux, Mac OS X or FreeBSD, the resulting binaries contain DWARFv3
+on Linux, Mac OS X, FreeBSD or NetBSD, the resulting binaries contain DWARFv3
debugging information that recent versions (>7.1) of the GDB debugger can
use to inspect a live process or a core dump.
'-s'
flag to the linker to omit the debug information
(for example, go build -ldflags "-s" prog.go
).
+
+The code generated by the gc
compiler includes inlining of
+function invocations and registerization of variables. These optimizations
+can sometimes make debugging with gdb
harder. To disable them
+when debugging, pass the flags -gcflags "-N -l"
to the
+go
command used to build the code being
+debugged.
+
(gdb) list (gdb) list line (gdb) list file.go:line @@ -172,7 +179,7 @@ $ gdb regexp.test -d $GOROOT If for some reason GDB still can't find that directory or that script, you can load it by hand by telling gdb (assuming you have the go sources in~/go/
): -+
(gdb) source ~/go/src/pkg/runtime/runtime-gdb.py diff --git a/doc/devel/release.html b/doc/devel/release.html index 986310610..3340d1e91 100644 --- a/doc/devel/release.html +++ b/doc/devel/release.html @@ -3,11 +3,8 @@ }-->This page summarizes the changes between official stable releases of Go. -Between releases we issue less stable -weekly snapshots. -The weekly snapshot history contains more detail, -and the Mercurial change log -has full details.
+The Mercurial change log +has the full details.To update to a specific release, use:
@@ -53,6 +50,10 @@ of maps using struct or array keys: It also includes many minor code and documentation fixes. ++go1.0.3 (released 2012/09/21) includes minor code and documentation fixes. +
+See the go1 release branch history for the complete list of changes.
diff --git a/doc/devel/weekly.html b/doc/devel/weekly.html index 46efe41ed..f8d3ec6dd 100644 --- a/doc/devel/weekly.html +++ b/doc/devel/weekly.html @@ -3,18 +3,9 @@ }-->This page summarizes the changes between tagged weekly snapshots of Go. -For full details, see the Mercurial change log.
+Such snapshots are no longer created. This page remains as a historical reference only. -Weekly snapshots occur often and may not be stable. -If stability of API and code is more important than having the -latest features, use the official releases instead.
- -To update to a specific snapshot, use:
- --hg pull -hg update weekly.YYYY-MM-DD -+For recent information, see the Mercurial change log and development mailing list.
2012-03-27 (Go 1)
diff --git a/doc/docs.html b/doc/docs.html index f88e930fb..3112381c2 100644 --- a/doc/docs.html +++ b/doc/docs.html @@ -45,8 +45,10 @@ learned. You can take the tour online orHow to write Go code
-How to use the go command to fetch, build, and install -packages, commands, and run tests. +Also available as a +screencast, this doc +explains how to use the go command to fetch, build, and +install packages, commands, and run tests.
Effective Go
@@ -56,10 +58,13 @@ A must read for any new Go programmer. It augments the tour and the language specification, both of which should be read first. -Getting Started with Go on App Engine
+Go References
+Language specification, memory model, and detailed documentation for the commands and packages.
+ +Getting Started with Go on App Engine
How to develop and deploy a simple Go project with -Google App Engine. +Google App Engine.
Frequently Asked Questions (FAQ)
@@ -127,6 +132,7 @@ Guided tours of Go programs.
-A talk by Rob Pike and Andrew Gerrand presented at Google I/O 2011. -It walks through the construction and deployment of a simple web application -and unveils the Go runtime for App Engine. -See the presentation slides. +Three things that make Go fast, fun, and productive: +interfaces, reflection, and concurrency. Builds a toy web crawler to +demonstrate these.
--A talk by Andrew Gerrand presented at Google I/O Bootcamp 2011. -It gives a broad overview of Go's type system and concurrency model -and provides four examples of Go programs that solve real problems. -See the presentation slides. +Concurrency is the key to designing high performance network services. Go's concurrency primitives (goroutines and channels) provide a simple and efficient means of expressing concurrent execution. In this talk we see how tricky concurrency problems can be solved gracefully with simple Go code.
--A talk by Andrew Gerrand presented at Google Developer Day Japan 2011. -It discusses the development of a web application that runs on Google -App Engine and renders images that it stores on Google Cloud Storage. +A panel discussion with David Symonds, Robert Griesemer, Rob Pike, Ken Thompson, Andrew Gerrand, and Brad Fitzpatrick. +
+ ++A talk by Rob Pike and Andrew Gerrand presented at Google I/O 2011. +It walks through the construction and deployment of a simple web application +and unveils the Go runtime for App Engine. +See the presentation slides.
-This talk presents the development of a complete web application in Go. -It looks at design, storage, concurrency, and scaling issues in detail, using -the simple example of an URL shortening service. -See the presentation slides. -
-
See the GoTalks
@@ -201,7 +201,7 @@ documentation.
The golang-nuts
mailing list is for general Go discussion. A list of external Go projects including programs and libraries.Go Project Dashboard
+Go Wiki Projects Page
Go IRC Channel
diff --git a/doc/effective_go.html b/doc/effective_go.html
index 6cacac630..e02694add 100644
--- a/doc/effective_go.html
+++ b/doc/effective_go.html
@@ -41,8 +41,14 @@ The Go package sources
are intended to serve not
only as the core library but also as examples of how to
use the language.
+Moreover, many of the packages contain working, self-contained
+executable examples you can run directly from the
+golang.org web site, such as
+this one (click
+on the word "Example" to open it up).
If you have a question about how to approach a problem or how something
-might be implemented, they can provide answers, ideas and
+might be implemented, the documentation, code and examples in the
+library can provide answers, ideas and
background.
gofmt
.
-Some formatting details remain. Very briefly, +Some formatting details remain. Very briefly:
if
,
+ Go needs fewer parentheses than C and Java: control structures (if
,
for
, switch
) do not have parentheses in
their syntax.
Also, the operator precedence hierarchy is shorter and clearer, so
x<<8 + y<<16- means what the spacing implies. + means what the spacing implies, unlike in the other languages.
/* */
block comments
and C++-style //
line comments.
Line comments are the norm;
-block comments appear mostly as package comments and
-are also useful to disable large swaths of code.
+block comments appear mostly as package comments, but
+are useful within an expression or to disable large swaths of code.
@@ -167,10 +173,9 @@ should set up the detailed documentation that follows.
/* - Package regexp implements a simple library for - regular expressions. +Package regexp implements a simple library for regular expressions. - The syntax of the regular expressions accepted is: +The syntax of the regular expressions accepted is: regexp: concatenation { '|' concatenation } @@ -206,6 +211,13 @@ takes care of that. The comments are uninterpreted plain text, so HTML and other annotations such as+_this_
will reproduce verbatim and should not be used. +One adjustmentgodoc
does do is to display indented +text in a fixed-width font, suitable for program snippets. +The package comment for the +fmt
package uses this to good effect. + + +Depending on the context,
godoc
might not even reformat comments, so make sure they look good straight up: use correct spelling, punctuation, and sentence structure, @@ -232,6 +244,33 @@ starts with the name being declared. func Compile(str string) (regexp *Regexp, err error) {
+If the name always begins the comment, the output of godoc
+can usefully be run through grep
.
+Imagine you couldn't remember the name "Compile" but were looking for
+the parsing function for regular expressions, so you ran
+the command,
+
+$ godoc regexp | grep parse ++ +
+If all the doc comments in the package began, "This function...", grep
+wouldn't help you remember the name. But because the package starts each
+doc comment with the name, you'd see something like this,
+which recalls the word you're looking for.
+
+$ godoc regexp | grep parse + Compile parses a regular expression and returns, if successful, a Regexp + parsed. It simplifies safe initialization of global variables holding + cannot be parsed. It simplifies safe initialization of global variables +$ ++
Go's declaration syntax allows grouping of declarations. A single doc comment can introduce a group of related constants or variables. @@ -266,7 +305,7 @@ var (
Names are as important in Go as in any other language.
-In some cases they even have semantic effect: for instance,
+They even have semantic effect:
the visibility of a name outside a package is determined by whether its
first character is upper case.
It's therefore worth spending a little time talking about naming conventions
@@ -311,11 +350,11 @@ not encoding_base64
and not encodingBase64
.
-The importer of a package will use the name to refer to its contents
-(the import .
notation is intended mostly for tests and other
-unusual situations and should be avoided unless necessary),
+The importer of a package will use the name to refer to its contents.
so exported names in the package can use that fact
to avoid stutter.
+(Don't use the import .
notation, which can simplify
+tests that must run outside the package they are testing, but should otherwise be avoided.)
For instance, the buffered reader type in the bufio
package is called Reader
,
not BufReader
, because users see it as bufio.Reader
,
which is a clear, concise name.
@@ -336,9 +375,7 @@ Another short example is once.Do
;
once.Do(setup)
reads well and would not be improved by
writing once.DoOrWaitUntilDone(setup)
.
Long names don't automatically make things more readable.
-If the name represents something intricate or subtle, it's usually better
-to write a helpful doc comment than to attempt to put all the information
-into the name.
+A helpful doc comment can often be more valuable than an extra long name.
-Like C, Go's formal grammar uses semicolons to terminate statements; -unlike C, those semicolons do not appear in the source. +Like C, Go's formal grammar uses semicolons to terminate statements, +but unlike in C, those semicolons do not appear in the source. Instead the lexer uses a simple rule to insert semicolons automatically as it scans, so the input text is mostly free of them.
@@ -432,7 +469,8 @@ statements on a line, should you write code that way.
-One caveat. You should never put the opening brace of a
+One consequence of the semicolon insertion rules
+is that you cannot put the opening brace of a
control structure (if
, for
, switch
,
or select
) on the next line. If you do, a semicolon
will be inserted before the brace, which could cause unwanted
@@ -541,7 +579,7 @@ codeUsing(f, d)
-
An aside: The last example in the previous section demonstrates a detail of how the @@ -578,7 +616,7 @@ if it has already been declared, provided:
v
-(if v
is already declared in an outer scope, the declaration will create a new variable),v
is already declared in an outer scope, the declaration will create a new variable §),v
, andif-else
chain.
You'll see it used often.
++§ It's worth noting here that in Go the scope of function parameters and return values +is the same as the function body, even though they appear lexically outside the braces +that enclose the body. +
+@@ -635,7 +679,7 @@ If you only need the first item in the range (the key or index), drop the second
for key := range m { - if expired(key) { + if key.expired() { delete(m, key) } } @@ -653,29 +697,30 @@ for _, value := range array {For strings, the
range
does more work for you, breaking out individual -Unicode characters by parsing the UTF-8. +Unicode code points by parsing the UTF-8. Erroneous encodings consume one byte and produce the replacement rune U+FFFD. The loop-for pos, char := range "日本語" { - fmt.Printf("character %c starts at byte position %d\n", char, pos) +for pos, char := range "日本\x80語" { // \x80 is an illegal UTF-8 encoding + fmt.Printf("character %#U starts at byte position %d\n", char, pos) }prints
-character 日 starts at byte position 0 -character 本 starts at byte position 3 -character 語 starts at byte position 6 +character U+65E5 '日' starts at byte position 0 +character U+672C '本' starts at byte position 3 +character U+FFFD '�' starts at byte position 6 +character U+8A9E '語' starts at byte position 7Finally, Go has no comma operator and
++
and--
are statements not expressions. Thus if you want to run multiple variables in afor
-you should use parallel assignment. +you should use parallel assignment (although that precludes++
and--
).// Reverse a @@ -714,6 +759,7 @@ func unhex(c byte) byte {There is no automatic fall through, but cases can be presented in comma-separated lists. +
func shouldEscape(c byte) bool { switch c { @@ -725,10 +771,11 @@ func shouldEscape(c byte) bool {-Here's a comparison routine for byte arrays that uses two +Here's a comparison routine for byte slices that uses two
switch
statements: +-// Compare returns an integer comparing the two byte arrays, +// Compare returns an integer comparing the two byte slices, // lexicographically. // The result will be 0 if a == b, -1 if a < b, and +1 if a > b func Compare(a, b []byte) int { @@ -756,19 +803,23 @@ variable. Such a type switch uses the syntax of a type assertion with the keywordtype
inside the parentheses. If the switch declares a variable in the expression, the variable will have the corresponding type in each clause. +It's also idiomatic to reuse the name in such cases, in effect declaring +a new variable with the same name but a different type in each case.-switch t := interfaceValue.(type) { +var t interface{} +t = functionOfSomeType() +switch t := t.(type) { default: - fmt.Printf("unexpected type %T", t) // %T prints type + fmt.Printf("unexpected type %T", t) // %T prints whatever type t has case bool: - fmt.Printf("boolean %t\n", t) + fmt.Printf("boolean %t\n", t) // t has type bool case int: - fmt.Printf("integer %d\n", t) + fmt.Printf("integer %d\n", t) // t has type int case *bool: - fmt.Printf("pointer to boolean %t\n", *t) + fmt.Printf("pointer to boolean %t\n", *t) // t has type *bool case *int: - fmt.Printf("pointer to integer %d\n", *t) + fmt.Printf("pointer to integer %d\n", *t) // t has type *int }@@ -808,7 +859,7 @@ This is a common style; see the section on error handling for more examples. A similar approach obviates the need to pass a pointer to a return value to simulate a reference parameter. Here's a simple-minded function to -grab a number from a position in a byte array, returning the number +grab a number from a position in a byte slice, returning the number and the next position. @@ -825,12 +876,12 @@ func nextInt(b []byte, i int) (int, int) {-You could use it to scan the numbers in an input array
a
like this: +You could use it to scan the numbers in an input sliceb
like this:- for i := 0; i < len(a); { - x, i = nextInt(a, i) + for i := 0; i < len(b); { + x, i = nextInt(b, i) fmt.Println(x) }@@ -1180,6 +1231,7 @@ structure with length 10 and a capacity of 100 pointing at the first for more information.) In contrast,new([]int)
returns a pointer to a newly allocated, zeroed slice structure, that is, a pointer to anil
slice value. +These examples illustrate the difference between
+new
and @@ -1330,6 +1382,8 @@ func Append(slice, data[]byte) []byte { We must return the slice afterwards because, althoughAppend
can modify the elements ofslice
, the slice itself (the run-time data structure holding the pointer, length, and capacity) is passed by value. +The idea of appending to a slice is so useful it's captured by the
append
built-in function. To understand that function's @@ -1369,8 +1423,8 @@ var timeZone = map[string] int {Assigning and fetching map values looks syntactically just like -doing the same for arrays except that the index doesn't need to -be an integer. +doing the same for arrays and slices except that the index doesn't +need to be an integer.
offset := timeZone["EST"] @@ -1495,7 +1549,7 @@ prints If you just want the default conversion, such as decimal for integers, you can use the catchall format%v
(for “value”); the result is exactly whatPrintln
would produce. -Moreover, that format can print any value, even arrays, structs, and +Moreover, that format can print any value, even arrays, slices, structs, and maps. Here is a print statement for the time zone map defined in the previous section.@@ -1539,12 +1593,13 @@ map[string] int{"CST":-21600, "PST":-28800, "EST":-18000, "UTC":0, "MST":-25200} That quoted string format is also available through%q
when applied to a value of typestring
or[]byte
; the alternate format%#q
will use backquotes instead if possible. -Also,%x
works on strings and arrays of bytes as well as on integers, -generating a long hexadecimal string, and with +Also,%x
works on strings, byte arrays and byte slices as well as +on integers, generating a long hexadecimal string, and with a space in the format (% x
) it puts spaces between the bytes.Another handy format is
%T
, which prints the type of a value. +fmt.Printf("%T\n", timeZone)@@ -1606,6 +1661,7 @@ func Println(v ...interface{}) { We write...
afterv
in the nested call toSprintln
to tell the compiler to treatv
as a list of arguments; otherwise it would just passv
as a single slice argument. +There's even more to printing than we've covered here. See the
godoc
documentation for packagefmt
for the details. @@ -1738,9 +1794,9 @@ initializer can be a general expression computed at run time.var ( - HOME = os.Getenv("HOME") - USER = os.Getenv("USER") - GOROOT = os.Getenv("GOROOT") + home = os.Getenv("HOME") + user = os.Getenv("USER") + goRoot = os.Getenv("GOROOT") )@@ -1763,17 +1819,17 @@ correctness of the program state before real execution begins.func init() { - if USER == "" { + if user == "" { log.Fatal("$USER not set") } - if HOME == "" { - HOME = "/usr/" + USER + if home == "" { + home = "/home/" + user } - if GOROOT == "" { - GOROOT = HOME + "/go" + if goRoot == "" { + goRoot = home + "/go" } - // GOROOT may be overridden by --goroot flag on command line. - flag.StringVar(&GOROOT, "goroot", GOROOT, "Go root directory") + // goRoot may be overridden by --goroot flag on command line. + flag.StringVar(&goRoot, "goroot", goRoot, "Go root directory") }@@ -1783,6 +1839,7 @@ func init() {Methods can be defined for any named type that is not a pointer or an interface; the receiver does not have to be a struct. +
In the discussion of slices above, we wrote an
Append
function. We can define it as a method on slices instead. To do @@ -2012,6 +2069,7 @@ Those methods include the standardWrite
method, so an can be used.Request
is a struct containing a parsed representation of the request from the client. +For brevity, let's ignore POSTs and assume HTTP requests are always GETs; that simplification does not affect the way the handlers are @@ -2034,6 +2092,7 @@ func (ctr *Counter) ServeHTTP(w http.ResponseWriter, req *http.Request) { (Keeping with our theme, note how
Fprintf
can print to anhttp.ResponseWriter
.) For reference, here's how to attach such a server to a node on the URL tree. +import "net/http" ... @@ -2187,6 +2246,7 @@ what aReader
does and what aWriter
does; it is a union of the embedded interfaces (which must be disjoint sets of methods). Only interfaces can be embedded within interfaces. +The same basic idea applies to structs, but with more far-reaching implications. The
bufio
package has two struct types, @@ -2378,10 +2438,11 @@ exits, silently. (The effect is similar to the Unix shell's background.)-go list.Sort() // run list.Sort concurrently; don't wait for it. +go list.Sort() // run list.Sort concurrently; don't wait for it.A function literal can be handy in a goroutine invocation. +
func Announce(message string, delay time.Duration) { go func() { @@ -2393,6 +2454,7 @@ func Announce(message string, delay time.Duration) {In Go, function literals are closures: the implementation makes sure the variables referred to by the function survive as long as they are active. +
These examples aren't too practical because the functions have no way of signaling completion. For that, we need channels. @@ -2425,7 +2487,7 @@ c := make(chan int) // Allocate a channel. // Start the sort in a goroutine; when it completes, signal on the channel. go func() { list.Sort() - c <- 1 // Send a signal; value does not matter. + c <- 1 // Send a signal; value does not matter. }() doSomethingForAWhile() <-c // Wait for sort to finish; discard sent value. @@ -2494,6 +2556,7 @@ One of the most important properties of Go is that a channel is a first-class value that can be allocated and passed around like any other. A common use of this property is to implement safe, parallel demultiplexing. +
In the example in the previous section,
handle
was an idealized handler for a request but we didn't define the @@ -2822,7 +2885,7 @@ func init() {When
@@ -2952,6 +3015,155 @@ filter unexpected problems and re-panic with the original error. That's left as an exercise for the reader. +panic
is called, including implicitly for run-time -errors such as indexing an array out of bounds or failing a type +errors such as indexing a slice out of bounds or failing a type assertion, it immediately stops execution of the current function and begins unwinding the stack of the goroutine, running any deferred functions along the way. If that unwinding reaches the top of the @@ -2923,7 +2986,7 @@ that it has the local typeError
. If it does not, the type assertion will fail, causing a run-time error that continues the stack unwinding as though nothing had interrupted it. This check means that if something unexpected happens, such -as an array index out of bounds, the code will fail even though we +as an index out of bounds, the code will fail even though we are usingpanic
andrecover
to handle user-triggered errors.Blank identifier
+ ++Go defines a special identifier
+ +_
, called the blank identifier. +The blank identifier can be used in a declaration to avoid +declaring a name, and it can be used in an assignment to discard a value. +This definition makes it useful in a variety of contexts. +Multiple assignment
+ ++If an assignment requires multiple values on the left side, +but one of the values will not be used by the program, +using the blank identifier in the assignment avoids the need +to create a dummy variable. +We saw one example of this in the discussion of +for loops above. +
++sum := 0 +for _, value := range array { + sum += value +} ++ ++Another common use is when calling a function that returns +a value and an error, but only the error is important. +
++if _, err := os.Stat(path); os.IsNotExist(err) { + fmt.Printf("%s does not exist\n", path) +} ++ ++A final use that is more common than it should be is to +discard the error from a function that is not expected to fail. +This is usually a mistake: when the function does fail, the code +will continue on and probably panic dereferencing a nil pointer. +
++// Always check errors: this program crashes if path does not exist. +fi, _ := os.Stat(path) +fmt.Printf("%s is %d bytes\n", path, fi.Size()) ++ +Unused imports and variables
+ ++Go defines that it is an error to import a package without using it, +or to declare a variable without using its value. +Unused imports bloat a program and lengthen compiles unnecessarily; +a variable that is initialized but not used is at least +a wasted computation and perhaps indicative of a +larger bug. +Of course, both of these situations also arise in programs +that are under active development, as you test and refine +your code. +
++For example, in this program, there are two unused imports +(
+{{code "/doc/progs/unused1.go" `/package/` `$`}} +fmt
andio
) +and an unused variable (greeting
). ++Top-level blank declarations referring to the packages +will silence the unused import errors. +By convention, these declarations should come immediately after +the imports, as a reminder to clean things up later. +Similarly, assigning
+{{code "/doc/progs/unused2.go" `/package/` `$`}} + +greeting
to a blank identifier +will silence the unused variable error. +Import for side effect
+ ++An unused import like
+fmt
orio
in the last section +should eventually be used or removed: +blank assignments identify code as a work in progress. +But sometimes it is useful to import a package only for its +side effects, without any explicit use. +For example, during itsinit
function, +thenet/http/pprof
+package registers HTTP handlers that provide useful +debugging information. It has an exported API too, but +most clients need only the handler registration. +In this situation, it is conventional to rename the package +to the blank identifier: ++import _ "net/http/pprof" +++This form of import makes clear that the package is being +imported for its side effects, because there is no other possible +use of the package: in this file, it doesn't have a name. +
+ +Interface checks
+ ++As we saw in the discussion of interfaces above, +Go does not require a type to declare explicitly that it implements an interface. +It implements the interface by simply implementing the required methods. +This makes Go programs more lightweight and flexible, and it can avoid +unnecessary dependencies between packages. +Most interface conversions are static, visible to the compiler, +and therefore checked at compile time. +For example, passing an
+*os.File
to a function +expecting anio.Reader
will not compile unless +*os.File
implements theio.Reader
interface. ++However, some types that are used only to satisfy dynamic interface checks. +For example, the
+encoding/json
+package defines aMarshaler
+interface. If the JSON encoder encounters a type implementing that interface, +the encoder will let the type convert itself to JSON instead of using the standard +conversion. +This check is done only at runtime, with code like: ++m, ok := val.(json.Marshaler) +++If a type—for example, +
+json.RawMessage
—intends +to customize its JSON representation, it should implement +json.Marshaler
, but there are no static conversions that would +cause the compiler to verify this automatically. +A declaration can be used to add such a check: ++var _ json.Marshaler = (*RawMessage)(nil) +++As part of type-checking this static assignment of a +
*RawMessage
to aMarshaler
, +the Go compiler will require that*RawMessage
implementsMarshaler
. +Using the blank identifier here indicates that +the declaration exists only for the type checking, +not to create a variable. +Conventionally, such declarations are used only when there are +no static conversions already present in the code. +A web server
@@ -2973,7 +3185,7 @@ for instance, a URL, saving you typing the URL into the phone's tiny keyboard. Here's the complete program. An explanation follows. -{{code "/doc/progs/eff_qr.go"}} +{{code "/doc/progs/eff_qr.go" `/package/` `$`}}The pieces up to
main
should be easy to follow. The one flag sets a default HTTP port for our server. The template @@ -2992,11 +3204,11 @@ server; it blocks while the server runs. executes the template on the data in the form value nameds
.-The template package is powerful; +The template package
html/template
is powerful; this program just touches on its capabilities. -In essence, it rewrites a piece of text on the fly by substituting elements derived +In essence, it rewrites a piece of HTML text on the fly by substituting elements derived from data items passed totempl.Execute
, in this case the -form value. +form value. Within the template text (templateStr
), double-brace-delimited pieces denote template actions. The piece from{{html "{{if .}}"}}
@@ -3005,13 +3217,14 @@ is non-empty. That is, when the string is empty, this piece of the template is suppressed.-The snippet
{{html "{{urlquery .}}"}}
says to process the data with the function -urlquery
, which sanitizes the query string -for safe display on the web page. +The two snippets{{html "{{.}}"}}
say to show the data presented to +the template—the query string—on the web page. +The HTML template package automatically provides appropriate escaping so the +text is safe to display.The rest of the template string is just the HTML to show when the page loads. -If this is too quick an explanation, see the documentation +If this is too quick an explanation, see the documentation for the template package for a more thorough discussion.
@@ -3025,7 +3238,7 @@ TODO
verifying implementation type Color uint32 - + // Check that Color implements image.Color and image.Image var _ image.Color = Black var _ image.Image = Black diff --git a/doc/gccgo_contribute.html b/doc/gccgo_contribute.html index 8ca13e4ef..4d268e02c 100644 --- a/doc/gccgo_contribute.html +++ b/doc/gccgo_contribute.html @@ -100,7 +100,9 @@ orgcc/testsuite/go.dg
directories in the GCC repository.Changes to the Go frontend should follow the same process as for the -main Go repository, only for the
diff --git a/doc/go1.1.html b/doc/go1.1.html new file mode 100644 index 000000000..ae0a09939 --- /dev/null +++ b/doc/go1.1.html @@ -0,0 +1,207 @@ + + +gofrontend
project -rather than thego
project. Those changes will then be -merged into the GCC sources. +main Go repository, only for thegofrontend
project and +thegofrontend-dev@googlegroups.com
mailing list +rather than thego
project and the +golang-dev@googlegroups.com
mailing list. Those changes +will then be merged into the GCC sources.Introduction to Go 1.1
+ +TODO + - overview + - link back to Go 1 and also Go 1 Compatibility docs. + +Changes to the language
+ +TODO + +Integer division by zero
+ ++In Go 1, integer division by a constant zero produced a runtime panic: +
+ ++func f(x int) int { + return x/0 +} ++ ++In Go 1.1, an integer division by constant zero is not a legal program, so it is a compile-time error. +
+ + +Changes to the implementations and tools
+ +TODO: more + +Command-line flag parsing
+ ++In the gc toolchain, the compilers and linkers now use the +same command-line flag parsing rules as the Go flag package, a departure +from the traditional Unix flag parsing. This may affect scripts that invoke +the tool directly. +For example, +
+ +go tool 6c -Fw -Dfoo
must now be written +go tool 6c -F -w -D foo
. +Size of int on 64-bit platforms
+ ++The language allows the implementation to choose whether the
+ +int
type anduint
types are 32 or 64 bits. Previous Go implementations madeint
anduint
32 bits on all systems. Both the gc and gccgo implementations (TODO: check that gccgo does) now makeint
anduint
64 bits on 64-bit platforms such as AMD64/x86-64. +Among other things, this enables the allocation of slices with +more than 2 billion elements on 64-bit platforms. ++Updating: +Most programs will be unaffected by this change. +Because Go does not allow implicit conversions between distinct +numeric types, +no programs will stop compiling due to this change. +However, programs that contain implicit assumptions +that
int
is only 32 bits may change behavior. +For example, this code prints a positive number on 64-bit systems and +a negative one on 32-bit systems: + ++x := ^uint32(0) // x is 0xffffffff +i := int(x) // i is -1 on 32-bit systems, 0xffffffff on 64-bit +fmt.Println(i) ++ +Portable code intending 32-bit sign extension (yielding -1 on all systems) +would instead say: +
+ ++i := int(int32(x)) ++ +Assembler
+ ++Due to the int and TODO: OTHER changes, +the placement of function arguments on the stack has changed. +Functions written in assembly will need to be revised at least +to adjust frame pointer offsets. +
+ +Changes to the go tool
+ +The
+ +go
tool has acquired several improvements which are intended to improve the experience for new Go users.Firstly, when compiling, testing, or running Go code, the
+ +go
tool will now give more detailed errors messages, including a list of paths searched, when a package cannot be located. ++$ go build foo/quxx +can't load package: package foo/quxx: cannot find package "foo/quxx" in any of: + /home/User/go/src/pkg/foo/quxx (from $GOROOT) + /home/User/src/foo/quxx (from $GOPATH) ++ ++Secondly, the
+ +go get
command no longer allows$GOROOT
as the default destination when downloading package source. To usego get
command, a valid$GOPATH
is now required. ++$ GOPATH= go get code.google.com/p/foo/quxx +package code.google.com/p/foo/quxx: cannot download, $GOPATH not set. For more details see: go help gopath ++ +Finally, as a result of the previous change, the
+ +go get
command will also fail when$GOPATH
and$GOROOT
are set to the same value. ++$ GOPATH=$GOROOT go get code.google.com/p/foo/quxx +warning: GOPATH set to GOROOT (/home/User/go) has no effect +package code.google.com/p/foo/quxx: cannot download, $GOPATH must not be set to $GOROOT. For more details see: go help gopath ++ +Changes to go fix
+ ++The
+ +go fix
command no longer applies fixes to update code from +before Go 1 to use Go 1 APIs. To update pre-Go 1 code to Go 1.1, use a Go 1.0 toolchain +to convert the code to Go 1.0 first. +Changes to the standard library
+ +debug/elf
++Previous versions of the debug/elf package intentionally skipped over the first +symbol in the ELF symbol table, since it is always an empty symbol. This symbol +is no longer skipped since indexes into the symbol table returned by debug/elf, +will be different to indexes into the original ELF symbol table. Any code that +calls the debug/elf functions Symbols or ImportedSymbols may need to be +adjusted to account for the additional symbol and the change in symbol offsets. +
+ +html/template
+ ++Templates using the undocumented and only partially implemented +"noescape" feature will break: that feature was removed. +
+ +net
+ ++The protocol-specific resolvers were formerly +lax about the network name passed in. For example, although the documentation was clear +that the only valid networks for
+ +ResolveTCPAddr
are"tcp"
, +"tcp4"
, and"tcp6"
, the Go 1.0 implementation silently accepted +any string. The Go 1.1 implementation returns an error if the network is not one of those strings. +The same is true of the other protocol-specific resolversResolveIPAddr
,ResolveUDPAddr
, and +ResolveUnixAddr
. ++The previous
+ +ListenUnixgram
returnedUDPConn
as +arepresentation of the connection endpoint. The Go 1.1 implementation +returnsUnixConn
to allow reading and writing +withReadFrom
andWriteTo
methods on +theUnixConn
. +time
++On FreeBSD, Linux, NetBSD, OS X and OpenBSD, previous versions of the time package +returned times with microsecond precision. The Go 1.1 implementation of time on these +systems now returns times with nanosecond precision. Code may exist that expects to be +able to store such a time in an external format with only microsecond precision, +read it back, and recover exactly the same time instant. +In Go 1.1 the same time will not be recovered, since the external storage +will have discarded nanoseconds. +To address this case, there are two new methods of time.Time, Round and Truncate, +that can be used to remove precision from a time before passing it to +external storage. +
+ +Exp and old subtrees moved to go.exp subrepo
+ ++To make it easier for binary distributions to access them if desired, the
+ +exp
+andold
source subtrees, which are not included in binary distributions, +have been moved to the newgo.exp
subrepository at +code.google.com/p/go.exp
. To access thessa
package, +for example, run ++$ go get code.google.com/p/go.exp/ssa ++ ++and then in Go source, +
+ ++import "code.google.com/p/go.exp/ssa" ++ +TODO
diff --git a/doc/go1.html b/doc/go1.html index e1afe479a..491fd7bf7 100644 --- a/doc/go1.html +++ b/doc/go1.html @@ -618,8 +618,6 @@ The packages in their new locations are:
old/netchan
old/regexp
old/template
@@ -639,6 +637,8 @@ Go 1 deletes several packages outright:
container/vector
exp/datafmt
go/typechecker
old/regexp
old/template
try
Visitor
interface value.
The WalkFunc
function will be called even for files or directories that could not be opened;
in such cases the error argument will describe the failure.
If a directory's contents are to be skipped,
-the function should return the value filepath.SkipDir
+the function should return the value filepath.SkipDir
{{code "/doc/progs/go1.go" `/STARTWALK/` `/ENDWALK/`}}
@@ -1865,7 +1865,7 @@ made easier with the new structure of the packages.
The imports will be updated by fix tool.
Single-template uses will be otherwise be largely unaffected.
Code that uses multiple templates in concert will need to be updated by hand.
-The examples in
+The examples in
the documentation for text/template
can provide guidance.
diff --git a/doc/go_faq.html b/doc/go_faq.html
index b5b7cc656..5c68aa7e5 100644
--- a/doc/go_faq.html
+++ b/doc/go_faq.html
@@ -1,5 +1,6 @@
+Go became a public open source project on November 10, 2009. +After a couple of years of very active design and development, stability was called for and +Go 1 was released +on March 28, 2012. +Go 1, which includes a language specification, +standard libraries, +and custom tools, +provides a stable foundation for creating reliable products, projects, and publications. +
+ ++With that stability established, we are using Go to develop programs, products, and tools rather than +actively changing the language and libraries. +In fact, the purpose of Go 1 is to provide long-term stability. +Backwards-incompatible changes will not be made to any Go 1 point release. +We want to use what we have to learn how a future version of Go might look, rather than to play with +the language underfoot. +
+ ++Of course, development will continue on Go itself, but the focus will be on performance, reliability, +portability and the addition of new functionality such as improved support for internationalization. +
+ ++There may well be a Go 2 one day, but not for a few years and it will be influenced by what we learn using Go 1 as it is today. +
+
-Yes. There are now several Go programs deployed in
+Yes. There are now several Go programs deployed in
production inside Google. A public example is the server behind
http://golang.org.
It's just the godoc
document server running in a production configuration on
-Google App Engine.
+Google App Engine.
gc
(the 6g
program and friends) and gccgo
.
Gc
uses a different calling convention and linker and can
therefore only be linked with C programs using the same convention.
-There is such a C compiler but no C++ compiler.
-Gccgo
is a GCC front-end that can, with care, be linked with
-GCC-compiled C or C++ programs.
+There is such a C compiler but no C++ compiler.
+Gccgo
is a GCC front-end that can, with care, be linked with
+GCC-compiled C or C++ programs.
-The cgo program provides the mechanism for a -“foreign function interface” to allow safe calling of +The cgo program provides the mechanism for a +“foreign function interface” to allow safe calling of C libraries from Go code. SWIG extends this capability to C++ libraries.
@@ -509,7 +542,7 @@ Why doesn't Go have "implements" declarations?A Go type satisfies an interface by implementing the methods of that interface, nothing more. This property allows interfaces to be defined and used without -having to modify existing code. It enables a kind of "duck typing" that +having to modify existing code. It enables a kind of structural typing that promotes separation of concerns and improves code re-use, and makes it easier to build on patterns that emerge as the code develops. The semantics of interfaces is one of the main reasons for Go's nimble, @@ -564,7 +597,7 @@ func (b Bar) Foo() {}
-Most code doesn't make use of such constraints, since they limit the utility of +Most code doesn't make use of such constraints, since they limit the utility of the interface idea. Sometimes, though, they're necessary to resolve ambiguities among similar interfaces.
@@ -890,6 +923,32 @@ See the document for more information about how to proceed. ++The Go project, hosted by Google Code at +code.google.com/p/go, +uses Mercurial as its version control system. +When the project launched, +Google Code supported only Subversion and Mercurial. +Mercurial was a better choice because of its plugin mechanism +that allowed us to create the "codereview" plugin to connect +the project to the excellent code review tools at +codereview.appspot.com. +
+ ++Programmers who work +with the Go project's source rather than release downloads sometimes +ask for the project to switch to git. +That would be possible, but it would be a lot of work and +would also require reimplementing the codereview plugin. +Given that Mercurial works today, with code review support, +combined with the Go project's mostly linear, non-branching use of +version control, a switch to git doesn't seem worthwhile. +
+int
32 bits on 64 bit machines?
The sizes of int
and uint
are implementation-specific
but the same as each other on a given platform.
-The 64 bit Go compilers (both gc and gccgo) use a 32 bit representation for
-int
. Code that relies on a particular
+For portability, code that relies on a particular
size of value should use an explicitly sized type, like int64
.
+Prior to Go 1.1, the 64-bit Go compilers (both gc and gccgo) used
+a 32-bit representation for int
. As of Go 1.1 they use
+a 64-bit representation.
On the other hand, floating-point scalars and complex
numbers are always sized: float32
, complex64
,
etc., because programmers should be aware of precision when using
@@ -1038,6 +1099,22 @@ analysis recognizes some cases when such variables will not
live past the return from the function and can reside on the stack.
+The Go memory allocator reserves a large region of virtual memory as an arena +for allocations. This virtual memory is local to the specific Go process; the +reservation does not deprive other processes of memory. +
+ +
+To find the amount of actual memory allocated to a Go process, use the Unix
+top
command and consult the RES
(Linux) or
+RSIZE
(Mac OS X) columns.
+
+
GOMAXPROCS
shell environment variable
or use the similarly-named function
of the runtime package to allow the
-run-time support to utilize more than one OS thread.
+run-time support to utilize more than one OS thread.
@@ -1084,7 +1161,7 @@ Why does using GOMAXPROCS
> 1 sometimes make my program
slower?
-It depends on the nature of your program. +It depends on the nature of your program. Problems that are intrinsically sequential cannot be sped up by adding more goroutines. Concurrency only becomes parallelism when the problem is @@ -1173,23 +1250,26 @@ func main() { // wait for all goroutines to complete before exiting for _ = range values { - <-done + <-done } }
-One might mistakenly expect to see a, b, c
as the output.
-What you'll probably see instead is c, c, c
. This is because
+One might mistakenly expect to see a, b, c
as the output.
+What you'll probably see instead is c, c, c
. This is because
each iteration of the loop uses the same instance of the variable v
, so
-each closure shares that single variable. When the closure runs, it prints the
+each closure shares that single variable. When the closure runs, it prints the
value of v
at the time fmt.Println
is executed,
-but v
may have been modified since the goroutine was launched.
+but v
may have been modified since the goroutine was launched.
+To help detect this and other problems before they happen, run
+go vet
.
-To bind the value of v
to each closure as they are launched, one
-could modify the inner loop to read:
+To bind the current value of v
to each closure as it is launched, one
+must modify the inner loop to create a new variable each iteration.
+One way is to pass the variable as an argument to the closure:
@@ -1202,11 +1282,26 @@ could modify the inner loop to read:
-In this example, the value of v
is passed as an argument to the
+In this example, the value of v
is passed as an argument to the
anonymous function. That value is then accessible inside the function as
the variable u
.
+Even easier is just to create a new variable, using a declaration style that may +seem odd but works fine in Go: +
+ ++ for _, v := range values { + v := v // create a new 'v'. + go func() { + fmt.Println(v) + done <- true + }() + } ++
See the How to Write Go Code document,
the testing
package
-and the go test
subcommand for more details.
+and the go test
subcommand for more details.
When developing code, it's common to create these situations temporarily and it can be annoying to have to edit them out before the -program will compile. +program will compile.
@@ -1430,13 +1525,13 @@ Why does Go perform badly on benchmark X?
One of Go's design goals is to approach the performance of C for comparable -programs, yet on some benchmarks it does quite poorly, including several -in test/bench/shootout. The slowest depend on libraries -for which versions of comparable performance are not available in Go. +programs, yet on some benchmarks it does quite poorly, including several +in test/bench/shootout. The slowest depend on libraries +for which versions of comparable performance are not available in Go. For instance, pidigits.go depends on a multi-precision math package, and the C versions, unlike Go's, use GMP (which is -written in optimized assembler). +written in optimized assembler). Benchmarks that depend on regular expressions (regex-dna.go, for instance) are essentially comparing Go's native regexp package to @@ -1455,7 +1550,7 @@ indicate.
Still, there is room for improvement. The compilers are good but could be better, many libraries need major performance work, and the garbage collector -isn't fast enough yet. (Even if it were, taking care not to generate unnecessary +isn't fast enough yet. (Even if it were, taking care not to generate unnecessary garbage can have a huge effect.)
diff --git a/doc/go_mem.html b/doc/go_mem.html index ece230638..0b73e43c4 100644 --- a/doc/go_mem.html +++ b/doc/go_mem.html @@ -270,8 +270,8 @@ before theprint
.
If the channel were buffered (e.g., c = make(chan int, 1)
)
then the program would not be guaranteed to print
-"hello, world"
. (It might print the empty string;
-it cannot print "goodbye, universe"
, nor can it crash.)
+"hello, world"
. (It might print the empty string,
+crash, or do something else.)
Each code point is distinct; for instance, upper and lower case letters @@ -99,6 +99,11 @@ are different characters. Implementation restriction: For compatibility with other tools, a compiler may disallow the NUL character (U+0000) in the source text.
++Implementation restriction: For compatibility with other tools, a +compiler may ignore a UTF-8-encoded byte order mark +(U+FEFF) if it is the first Unicode code point in the source text. +
-In The Unicode Standard 6.0, +In The Unicode Standard 6.2, Section 4.5 "General Category" defines a set of character categories. Go treats those characters in category Lu, Ll, Lt, Lm, or Lo as Unicode letters, @@ -198,7 +203,7 @@ token is integer, floating-point, imaginary, - character, or + rune, or string literal @@ -360,13 +365,15 @@ imaginary_lit = (decimals | float_lit) "i" . -
-A character literal represents a character constant, -typically a Unicode code point, as one or more characters enclosed in single -quotes. Within the quotes, any character may appear except single -quote and newline. A single quoted character represents itself, +A rune literal represents a rune constant, +an integer value identifying a Unicode code point. +A rune literal is expressed as one or more characters enclosed in single quotes. +Within the quotes, any character may appear except single +quote and newline. A single quoted character represents the Unicode value +of the character itself, while multi-character sequences beginning with a backslash encode values in various formats.
@@ -380,8 +387,8 @@ a literala
, Unicode U+0061, value 0x61
, while
a literal a
-dieresis, U+00E4, value 0xe4
.
-Several backslash escapes allow arbitrary values to be represented
-as ASCII text. There are four ways to represent the integer value
+Several backslash escapes allow arbitrary values to be encoded as
+ASCII text. There are four ways to represent the integer value
as a numeric constant: \x
followed by exactly two hexadecimal
digits; \u
followed by exactly four hexadecimal digits;
\U
followed by exactly eight hexadecimal digits, and a
@@ -409,14 +416,14 @@ After a backslash, certain single-character escapes represent special values:
\t U+0009 horizontal tab
\v U+000b vertical tab
\\ U+005c backslash
-\' U+0027 single quote (valid escape only within character literals)
+\' U+0027 single quote (valid escape only within rune literals)
\" U+0022 double quote (valid escape only within string literals)
-All other sequences starting with a backslash are illegal inside character literals. +All other sequences starting with a backslash are illegal inside rune literals.
-char_lit = "'" ( unicode_value | byte_value ) "'" . +rune_lit = "'" ( unicode_value | byte_value ) "'" . unicode_value = unicode_char | little_u_value | big_u_value | escaped_char . byte_value = octal_byte_value | hex_byte_value . octal_byte_value = `\` octal_digit octal_digit octal_digit . @@ -439,6 +446,11 @@ escaped_char = `\` ( "a" | "b" | "f" | "n" | "r" | "t" | "v" | `\` | "'" | ` '\xff' '\u12e4' '\U00101234' +'aa' // illegal: too many characters +'\xa' // illegal: too few hexadecimal digits +'\0' // illegal: too few octal digits +'\uDFFF' // illegal: surrogate half +'\U00110000' // illegal: invalid Unicode code point@@ -453,7 +465,8 @@ raw string literals and interpreted string literals. Raw string literals are character sequences between back quotes
``
. Within the quotes, any character is legal except
back quote. The value of a raw string literal is the
-string composed of the uninterpreted characters between the quotes;
+string composed of the uninterpreted (implicitly UTF-8-encoded) characters
+between the quotes;
in particular, backslashes have no special meaning and the string may
contain newlines.
Carriage returns inside raw string literals
@@ -464,8 +477,9 @@ Interpreted string literals are character sequences between double
quotes ""
. The text between the quotes,
which may not contain newlines, forms the
value of the literal, with backslash escapes interpreted as they
-are in character literals (except that \'
is illegal and
-\"
is legal). The three-digit octal (\
nnn)
+are in rune literals (except that \'
is illegal and
+\"
is legal), with the same restrictions.
+The three-digit octal (\
nnn)
and two-digit hexadecimal (\x
nn) escapes represent individual
bytes of the resulting string; all other escapes represent
the (possibly multi-byte) UTF-8 encoding of individual characters.
@@ -492,6 +506,8 @@ interpreted_string_lit = `"` { unicode_value | byte_value } `"` .
"日本語"
"\u65e5本\U00008a9e"
"\xff\u00FF"
+"\uD800" // illegal: surrogate half
+"\U00110000" // illegal: invalid Unicode code point
@@ -501,15 +517,15 @@ These examples all represent the same string:
"日本語" // UTF-8 input text `日本語` // UTF-8 input text as a raw literal -"\u65e5\u672c\u8a9e" // The explicit Unicode code points -"\U000065e5\U0000672c\U00008a9e" // The explicit Unicode code points -"\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e" // The explicit UTF-8 bytes +"\u65e5\u672c\u8a9e" // the explicit Unicode code points +"\U000065e5\U0000672c\U00008a9e" // the explicit Unicode code points +"\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e" // the explicit UTF-8 bytes
If the source code represents a character as two code points, such as a combining form involving an accent and a letter, the result will be -an error if placed in a character literal (it is not a single code +an error if placed in a rune literal (it is not a single code point), and will appear as two code points if placed in a string literal.
@@ -518,7 +534,7 @@ literal.There are boolean constants, -character constants, +rune constants, integer constants, floating-point constants, complex constants, and string constants. Character, integer, floating-point, @@ -528,7 +544,7 @@ collectively called numeric constants.
A constant value is represented by a -character, +rune, integer, floating-point, imaginary, @@ -622,14 +638,15 @@ expressions.
A type determines the set of values and operations specific to values of that -type. A type may be specified by a (possibly qualified) type name -(§Qualified identifier, §Type declarations) or a type literal, +type. A type may be specified by a +(possibly qualified) type name +(§Type declarations) or a type literal, which composes a new type from previously declared types.
Type = TypeName | TypeLit | "(" Type ")" . -TypeName = QualifiedIdent . +TypeName = identifier | QualifiedIdent . TypeLit = ArrayType | StructType | PointerType | FunctionType | InterfaceType | SliceType | MapType | ChannelType .@@ -646,7 +663,7 @@ type literals. The static type (or just type) of a variable is the type defined by its declaration. Variables of interface type also have a distinct dynamic type, which -is the actual type of the value stored in the variable at run-time. +is the actual type of the value stored in the variable at run time. The dynamic type may vary during execution but is always assignable to the static type of the interface variable. For non-interface @@ -764,19 +781,21 @@ particular architecture.
A string type represents the set of string values.
-Strings behave like slices of bytes but are immutable: once created,
+A string value is a (possibly empty) sequence of bytes.
+Strings are immutable: once created,
it is impossible to change the contents of a string.
The predeclared string type is string
.
+
-The elements of strings have type byte
and may be
-accessed using the usual indexing operations. It is
-illegal to take the address of such an element; if
-s[i]
is the ith byte of a
-string, &s[i]
is invalid. The length of string
-s
can be discovered using the built-in function
-len
. The length is a compile-time constant if s
-is a string literal.
+The length of a string s
(its size in bytes) can be discovered using
+the built-in function len
.
+The length is a compile-time constant if the string is a constant.
+A string's bytes can be accessed by integer indices
+0 through len(s)-1
.
+It is illegal to take the address of such an element; if
+s[i]
is the i
'th byte of a
+string, &s[i]
is invalid.
-The length is part of the array's type and must be a
-constant expression that evaluates to a non-negative
-integer value. The length of array a
can be discovered
-using the built-in function len(a)
.
-The elements can be indexed by integer
-indices 0 through len(a)-1
(§Indexes).
+The length is part of the array's type; it must evaluate to a non-
+negative constant representable by a value
+of type int
.
+The length of array a
can be discovered
+using the built-in function len
.
+The elements can be addressed by integer indices
+0 through len(a)-1
.
Array types are always one-dimensional but may be composed to form
multi-dimensional types.
Like arrays, slices are indexable and have a length. The length of a
slice s
can be discovered by the built-in function
-len(s)
; unlike with arrays it may change during
-execution. The elements can be addressed by integer indices 0
-through len(s)-1
(§Indexes). The slice index of a
+len
; unlike with arrays it may change during
+execution. The elements can be addressed by integer indices
+0 through len(s)-1
. The slice index of a
given element may be less than the index of the same element in the
underlying array.
T
. The method set of *S
also
includes promoted methods with receiver *T
.
-
+
S
contains an anonymous field *T
,
the method sets of S
and *S
both
@@ -994,7 +1014,7 @@ promoted methods are included in the method set of the struct as follows:
A field declaration may be followed by an optional string literal tag,
which becomes an attribute for all the fields in the corresponding
field declaration. The tags are made
-visible through a reflection interface
+visible through a reflection interface
but are otherwise ignored.
@@ -1046,8 +1066,11 @@ ParameterDecl = [ IdentifierList ] [ "..." ] Type .
Within a list of parameters or results, the names (IdentifierList) must either all be present or all be absent. If present, each name -stands for one item (parameter or result) of the specified type; if absent, each -type stands for one item of that type. Parameter and result +stands for one item (parameter or result) of the specified type and +all non-blank names in the signature +must be unique. +If absent, each type stands for one item of that type. +Parameter and result lists are always parenthesized except that if there is exactly one unnamed result it may be written as an unparenthesized type.
@@ -1232,10 +1255,10 @@ map[string]interface{}
The number of map elements is called its length.
For a map m
, it can be discovered using the
-built-in function len(m)
+built-in function len
and may change during execution. Elements may be added during execution
using assignments and retrieved with
-index expressions; they may be removed with the
+index expressions; they may be removed with the
delete
built-in function.
@@ -1510,11 +1533,11 @@ Go is lexically scoped using blocks: or function (but not method) declared at top level (outside any function) is the package block.
Unlike regular variable declarations, a short variable declaration may redeclare variables provided they -were originally declared in the same block with the same type, and at +were originally declared earlier in the same block with the same type, and at least one of the non-blank variables is new. As a consequence, redeclaration can only appear in a multi-variable short declaration. Redeclaration does not introduce a new @@ -1907,6 +1930,7 @@ variable; it just assigns a new value to the original.
field1, offset := nextField(str, 0) field2, offset := nextField(str, offset) // redeclares offset +a, a := 1, 2 // illegal: double declaration of a or no new variable if a was declared elsewhere
@@ -1969,8 +1993,15 @@ is visible only within selectors for that type.
-For a base type, the non-blank names of -methods bound to it must be unique. +A non-blank receiver identifier must be +unique in the method signature. +If the receiver's value is not referenced inside the body of the method, +its identifier may be omitted in the declaration. The same applies in +general to parameters of functions and methods. +
+ ++For a base type, the non-blank names of methods bound to it must be unique. If the base type is a struct type, the non-blank method and field names must be distinct.
@@ -1996,12 +2027,6 @@ with receiver type*Point
,
to the base type Point
.
--If the receiver's value is not referenced inside the body of the method, -its identifier may be omitted in the declaration. The same applies in -general to parameters of functions and methods. -
-
The type of a method is the type of a function with the receiver as first
argument. For instance, the method Scale
has type
@@ -2026,25 +2051,33 @@ operators and functions to operands.
-Operands denote the elementary values in an expression. +Operands denote the elementary values in an expression. An operand may be a +literal, a (possibly qualified) identifier +denoting a +constant, +variable, or +function, +a method expression yielding a function, +or a parenthesized expression.
-Operand = Literal | QualifiedIdent | MethodExpr | "(" Expression ")" . +Operand = Literal | OperandName | MethodExpr | "(" Expression ")" . Literal = BasicLit | CompositeLit | FunctionLit . -BasicLit = int_lit | float_lit | imaginary_lit | char_lit | string_lit . +BasicLit = int_lit | float_lit | imaginary_lit | rune_lit | string_lit . +OperandName = identifier | QualifiedIdent.-
-A qualified identifier is a non-blank identifier -qualified by a package name prefix. +A qualified identifier is an identifier qualified with a package name prefix. +Both the package name and the identifier must not be +blank.
-QualifiedIdent = [ PackageName "." ] identifier . +QualifiedIdent = PackageName "." identifier .
@@ -2089,7 +2122,7 @@ The types of the expressions must be assignable to the respective field, element, and key types of the LiteralType; there is no additional conversion. The key is interpreted as a field name for struct literals, -an index expression for array and slice literals, and a key for map literals. +an index for array and slice literals, and a key for map literals. For map literals, all elements must have a key. It is an error to specify multiple elements with the same field name or constant key value. @@ -2101,18 +2134,18 @@ For struct literals the following rules apply:
T
,
elements that are themselves composite literals may elide the respective
literal type if it is identical to the element type of T
.
Similarly, elements that are addresses of composite literals may elide
-the &T
when the the element type is *T
.
+the &T
when the element type is *T
.
@@ -2315,7 +2348,6 @@ Point{1, 2}
m["foo"]
s[i : j + 1]
obj.color
-math.Sin
f.p[i].x()
@@ -2323,7 +2355,9 @@ f.p[i].x()
-A primary expression of the form
+For a primary expression x
+that is not a package name, the
+selector expression
@@ -2331,17 +2365,20 @@ x.f
-denotes the field or method f
of the value denoted by x
-(or sometimes *x
; see below). The identifier f
-is called the (field or method)
-selector; it must not be the blank identifier.
-The type of the expression is the type of f
.
+denotes the field or method f
of the value x
+(or sometimes *x
; see below).
+The identifier f
is called the (field or method) selector;
+it must not be the blank identifier.
+The type of the selector expression is the type of f
.
+If x
is a package name, see the section on
+qualified identifiers.
A selector f
may denote a field or method f
of
a type T
, or it may refer
-to a field or method f
of a nested anonymous field of
-T
.
+to a field or method f
of a nested
+anonymous field of T
.
The number of anonymous fields traversed
to reach f
is called its depth in T
.
The depth of a field or method f
@@ -2350,9 +2387,11 @@ The depth of a field or method f
declared in
an anonymous field A
in T
is the
depth of f
in A
plus one.
The following rules apply to selectors:
+x
of type T
or *T
@@ -2364,18 +2403,26 @@ If there is not exactly one f
<
with shallowest depth, the selector expression is illegal.
x
of type I
-where I
is an interface type,
-x.f
denotes the actual method with name f
of the value assigned
-to x
if there is such a method.
-If no value or nil
was assigned to x
, x.f
is illegal.
+For a variable x
of type I
where I
+is an interface type, x.f
denotes the actual method with name
+f
of the value assigned to x
.
+If there is no method with name f
in the
+method set of I
, the selector
+expression is illegal.
x.f
is illegal.
x
is of pointer or interface type and has the value
+nil
, assigning to, evaluating, or calling x.f
+causes a run-time panic.
+
-Selectors automatically dereference pointers to structs.
+Selectors automatically dereference
+pointers to structs.
If x
is a pointer to a struct, x.y
is shorthand for (*x).y
; if the field y
is also a pointer to a struct, x.y.z
is shorthand
@@ -2384,6 +2431,7 @@ If x
contains an anonymous field of type *A
,
where A
is also a struct type,
x.f
is a shortcut for (*x.A).f
.
For example, given the declarations:
@@ -2421,9 +2469,9 @@ p.z // (*p).z p.y // ((*p).T1).y p.x // (*(*p).T0).x -p.M2 // (*p).M2 -p.M1 // ((*p).T1).M1 -p.M0 // ((*p).T0).M0 +p.M2() // (*p).M2() +p.M1() // ((*p).T1).M1() +p.M0() // ((*p).T0).M0() @@ -2434,7 +2482,7 @@ TODO: Specify what happens to receivers. --> -
A primary expression of the form
@@ -2451,17 +2499,36 @@ The value x
is called the
rules apply:
+If a
is not a map:
+
x
must be an integer value; it is in range if 0 <= x < len(a)
,
+ otherwise it is out of rangeint
+
For a
of type A
or *A
-where A
is an array type,
-or for a
of type S
where S
is a slice type:
+where A
is an array type:
x
must be an integer value and 0 <= x < len(a)
a
is nil
or if x
is out of range at run time,
+ a run-time panic occursa[x]
is the array element at index x
and the type of
- a[x]
is the element type of A
a
is nil
or if the index x
is out of range,
- a run-time panic occursa[x]
is the element type of A
+For a
of type S
where S
is a slice type:
+
nil
or if x
is out of range at run time,
+ a run-time panic occursa[x]
is the slice element at index x
and the type of
+ a[x]
is the element type of S
@@ -2469,12 +2536,13 @@ For a
of type T
where T
is a string type:
x
must be an integer value and 0 <= x < len(a)
a
is also constantx
is out of range at run time,
+ a run-time panic occursa[x]
is the byte at index x
and the type of
- a[x]
is byte
a[x]
is byte
a[x]
may not be assigned tox
is out of range,
- a run-time panic occurs
@@ -2483,14 +2551,14 @@ where M
is a map type:
x
's type must be
- assignable
- to the key type of M
M
x
,
- a[x]
is the map value with key x
- and the type of a[x]
is the value type of M
a[x]
is the map value with key x
+ and the type of a[x]
is the value type of M
nil
or does not contain such an entry,
- a[x]
is the zero value
- for the value type of M
a[x]
is the zero value
+ for the value type of M
@@ -2533,9 +2601,9 @@ a[low : high]
-constructs a substring or slice. The index expressions low
and
+constructs a substring or slice. The indices low
and
high
select which elements appear in the result. The result has
-indexes starting at 0 and length equal to
+indices starting at 0 and length equal to
high
- low
.
After slicing the array a
-For convenience, any of the index expressions may be omitted. A missing low
+For convenience, any of the indices may be omitted. A missing low
index defaults to zero; a missing high
index defaults to the length of the
sliced operand:
-For arrays or strings, the indexes low
and high
must
-satisfy 0 <= low
<= high
<= length; for
-slices, the upper bound is the capacity rather than the length.
+For arrays or strings, the indices low
and high
are
+in range if 0
<= low
<= high
<= len(a)
,
+otherwise they are out of range.
+For slices, the upper index bound is the slice capacity cap(a)
rather than the length.
+A constant index must be non-negative and representable by a value of type
+int
.
+If both indices
+are constant, they must satisfy low <= high
. If a
is nil
+or if the indices are out of range at run time, a run-time panic occurs.
@@ -2601,19 +2675,33 @@ The notation x.(T)
is called a type assertion.
More precisely, if T
is not an interface type, x.(T)
asserts
that the dynamic type of x
is identical
to the type T
.
+In this case, T
must implement the (interface) type of x
;
+otherwise the type assertion is invalid since it is not possible for x
+to store a value of type T
.
If T
is an interface type, x.(T)
asserts that the dynamic type
-of x
implements the interface T
(§Interface types).
+of x
implements the interface T
.
If the type assertion holds, the value of the expression is the value
stored in x
and its type is T
. If the type assertion is false,
a run-time panic occurs.
In other words, even though the dynamic type of x
-is known only at run-time, the type of x.(T)
is
+is known only at run time, the type of x.(T)
is
known to be T
in a correct program.
+var x interface{} = 7 // x has dynamic type int and value 7 +i := x.(int) // i has type int and value 7 + +type I interface { m() } +var y I +s := y.(string) // illegal: string does not implement I (missing method m) +r := y.(io.Reader) // r has type io.Reader and y must implement both I and io.Reader ++
-If a type assertion is used in an assignment or initialization of the form +If a type assertion is used in an assignment or initialization of the form
@@ -2629,7 +2717,7 @@ otherwise, the expression returns(Z, false)
whereZ
is the zero value for typeT
. No run-time panic occurs in this case. The type assertion in this construct thus acts like a function call -returning a value and a boolean indicating success. (§Assignments) +returning a value and a boolean indicating success. @@ -2677,13 +2765,14 @@ causes a run-time panic.-As a special case, if the return parameters of a function or method +As a special case, if the return values of a function or method
g
are equal in number and individually assignable to the parameters of another function or methodf
, then the callf(g(parameters_of_g))
will invokef
after binding the return values ofg
to the parameters off
in order. The call -off
must contain no parameters other than the call ofg
. +off
must contain no parameters other than the call ofg
, +andg
must have at least one return value. Iff
has a final...
parameter, it is assigned the return values ofg
that remain after assignment of regular parameters. @@ -2834,8 +2923,8 @@ As a consequence, statement*p++
is the same as(*p)++
There are five precedence levels for binary operators. Multiplication operators bind strongest, followed by addition -operators, comparison operators,
&&
(logical and), -and finally||
(logical or): +operators, comparison operators,&&
(logical AND), +and finally||
(logical OR):@@ -2878,10 +2967,10 @@ to strings. All other arithmetic operators apply to integers only. / quotient integers, floats, complex values % remainder integers -& bitwise and integers -| bitwise or integers -^ bitwise xor integers -&^ bit clear (and not) integers +& bitwise AND integers +| bitwise OR integers +^ bitwise XOR integers +&^ bit clear (AND NOT) integers << left shift integer << unsigned integer >> right shift integer >> unsigned integer @@ -2938,10 +3027,11 @@ int64 -9223372036854775808-If the divisor is zero, a run-time panic occurs. -If the dividend is positive and the divisor is a constant power of 2, +If the divisor is a constant, it must not be zero. +If the divisor is zero at run time, a run-time panic occurs. +If the dividend is non-negative and the divisor is a constant power of 2, the division may be replaced by a right shift, and computing the remainder may -be replaced by a bitwise "and" operation: +be replaced by a bitwise AND operation:
@@ -2976,10 +3066,10 @@ follows:-For floating-point numbers, +For floating-point and complex numbers,
@@ -3142,9 +3232,9 @@ The right operand is evaluated conditionally.+x
is the same asx
, while-x
is the negation ofx
. -The result of a floating-point division by zero is not specified beyond the +The result of a floating-point or complex division by zero is not specified beyond the IEEE-754 standard; whether a run-time panic occurs is implementation-specific.-&& conditional and p && q is "if p then q else false" -|| conditional or p || q is "if p then true else q" -! not !p is "not p" +&& conditional AND p && q is "if p then q else false" +|| conditional OR p || q is "if p then true else q" +! NOT !p is "not p"@@ -3158,6 +3248,7 @@ that is, either a variable, pointer indirection, or slice indexing operation; or a field selector of an addressable struct operand; or an array indexing operation of an addressable array. As an exception to the addressability requirement,x
may also be a +(possibly parenthesized) composite literal.@@ -3171,6 +3262,7 @@ will cause a run-time panic.
&x &a[f(2)] +&Point{2, 3} *p *pf(x)@@ -3181,9 +3273,13 @@ will cause a run-time panic.For an operand
ch
of channel type, the value of the receive operation<-ch
is the value received -from the channelch
. The type of the value is the element type of -the channel. The expression blocks until a value is available. +from the channelch
. The channel direction must permit receive operations, +and the type of the receive operation is the element type of the channel. +The expression blocks until a value is available. Receiving from anil
channel blocks forever. +Receiving from a closed channel always succeeds, +immediately returning the element type's zero +value.@@ -3204,11 +3300,11 @@ var x, ok = <-ch-yields an additional result. -The boolean variable
- -ok
indicates whether -the received value was sent on the channel (true
) -or is a zero value returned -because the channel is closed and empty (false
). +yields an additional result of typebool
reporting whether the +communication succeeded. The value ofok
istrue
+if the value received was delivered by a successful send operation to the +channel, orfalse
if it is a zero value generated because the +channel is closed and empty.- -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- -- - -