1
0
mirror of https://github.com/golang/go synced 2024-11-24 00:00:23 -07:00

cmd/godoc: add support for serving templates

doc: convert to use godoc built-in templates

tmpltohtml is gone, to avoid having a second copy of the code.
Instead, godoc -url /doc/go1.html will print the actual HTML
served for that URL.  "make" will generate files named go1.rawhtml
etc, which can be fed through tidy.

It can be hard to tell from the codereview diffs, but all the
tmpl files have been renamed to be html files and then
have "Template": true added.

R=golang-dev, adg, r, gri
CC=golang-dev
https://golang.org/cl/5782046
This commit is contained in:
Russ Cox 2012-03-08 08:39:20 -05:00
parent e38c5fb23d
commit a40065ac68
17 changed files with 199 additions and 7357 deletions

View File

@ -2,21 +2,18 @@
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
HTML=\
articles/defer_panic_recover.html\
articles/error_handling.html\
articles/slices_usage_and_internals.html\
articles/laws_of_reflection.html\
effective_go.html\
go1.html\
RAWHTML=\
articles/defer_panic_recover.rawhtml\
articles/error_handling.rawhtml\
articles/slices_usage_and_internals.rawhtml\
articles/laws_of_reflection.rawhtml\
effective_go.rawhtml\
go1.rawhtml\
all: tmpltohtml $(HTML)
all: $(RAWHTML)
tmpltohtml: tmpltohtml.go
go build tmpltohtml.go
%.html: %.tmpl tmpltohtml
./tmpltohtml $*.tmpl > $@
%.rawhtml: %.html
godoc -url /doc/$* >$@
clean:
rm -f $(HTML) tmpltohtml
rm -f $(RAWHTML)

View File

@ -1,10 +1,7 @@
<!--{
"Title": "Defer, Panic, and Recover"
"Title": "Defer, Panic, and Recover",
"Template": true
}-->
<!--
DO NOT EDIT: created by
tmpltohtml articles/defer_panic_recover.tmpl
-->
<p>
Go has the usual mechanisms for control flow: if, for, switch, goto. It also
@ -23,23 +20,7 @@ For example, let's look at a function that opens two files and copies the
contents of one file to the other:
</p>
<pre><!--{{code "progs/defer.go" `/func CopyFile/` `/STOP/`}}
-->func CopyFile(dstName, srcName string) (written int64, err error) {
src, err := os.Open(srcName)
if err != nil {
return
}
dst, err := os.Create(dstName)
if err != nil {
return
}
written, err = io.Copy(dst, src)
dst.Close()
src.Close()
return
}</pre>
{{code "/doc/progs/defer.go" `/func CopyFile/` `/STOP/`}}
<p>
This works, but there is a bug. If the call to os.Create fails, the
@ -50,22 +31,7 @@ noticed and resolved. By introducing defer statements we can ensure that the
files are always closed:
</p>
<pre><!--{{code "progs/defer2.go" `/func CopyFile/` `/STOP/`}}
-->func CopyFile(dstName, srcName string) (written int64, err error) {
src, err := os.Open(srcName)
if err != nil {
return
}
defer src.Close()
dst, err := os.Create(dstName)
if err != nil {
return
}
defer dst.Close()
return io.Copy(dst, src)
}</pre>
{{code "/doc/progs/defer2.go" `/func CopyFile/` `/STOP/`}}
<p>
Defer statements allow us to think about closing each file right after opening
@ -88,13 +54,7 @@ In this example, the expression "i" is evaluated when the Println call is
deferred. The deferred call will print "0" after the function returns.
</p>
<pre><!--{{code "progs/defer.go" `/func a/` `/STOP/`}}
-->func a() {
i := 0
defer fmt.Println(i)
i++
return
}</pre>
{{code "/doc/progs/defer.go" `/func a/` `/STOP/`}}
<p>
2. <i>Deferred function calls are executed in Last In First Out order
@ -105,12 +65,7 @@ deferred. The deferred call will print "0" after the function returns.
This function prints "3210":
</p>
<pre><!--{{code "progs/defer.go" `/func b/` `/STOP/`}}
-->func b() {
for i := 0; i &lt; 4; i++ {
defer fmt.Print(i)
}
}</pre>
{{code "/doc/progs/defer.go" `/func b/` `/STOP/`}}
<p>
3. <i>Deferred functions may read and assign to the returning function's named
@ -122,11 +77,7 @@ In this example, a deferred function increments the return value i <i>after</i>
the surrounding function returns. Thus, this function returns 2:
</p>
<pre><!--{{code "progs/defer.go" `/func c/` `/STOP/`}}
-->func c() (i int) {
defer func() { i++ }()
return 1
}</pre>
{{code "/doc/progs/defer.go" `/func c/` `/STOP/`}}
<p>
This is convenient for modifying the error return value of a function; we will
@ -156,36 +107,7 @@ to panic and resume normal execution.
Here's an example program that demonstrates the mechanics of panic and defer:
</p>
<pre><!--{{code "progs/defer2.go" `/package main/` `/STOP/`}}
-->package main
import &#34;fmt&#34;
func main() {
f()
fmt.Println(&#34;Returned normally from f.&#34;)
}
func f() {
defer func() {
if r := recover(); r != nil {
fmt.Println(&#34;Recovered in f&#34;, r)
}
}()
fmt.Println(&#34;Calling g.&#34;)
g(0)
fmt.Println(&#34;Returned normally from g.&#34;)
}
func g(i int) {
if i &gt; 3 {
fmt.Println(&#34;Panicking!&#34;)
panic(fmt.Sprintf(&#34;%v&#34;, i))
}
defer fmt.Println(&#34;Defer in g&#34;, i)
fmt.Println(&#34;Printing in g&#34;, i)
g(i + 1)
}</pre>
{{code "/doc/progs/defer2.go" `/package main/` `/STOP/`}}
<p>
The function g takes the int i, and panics if i is greater than 3, or else it

View File

@ -1,195 +0,0 @@
<!--{
"Title": "Defer, Panic, and Recover"
}-->
{{donotedit}}
<p>
Go has the usual mechanisms for control flow: if, for, switch, goto. It also
has the go statement to run code in a separate goroutine. Here I'd like to
discuss some of the less common ones: defer, panic, and recover.
</p>
<p>
A <b>defer statement</b> pushes a function call onto a list. The list of saved
calls is executed after the surrounding function returns. Defer is commonly
used to simplify functions that perform various clean-up actions.
</p>
<p>
For example, let's look at a function that opens two files and copies the
contents of one file to the other:
</p>
{{code "progs/defer.go" `/func CopyFile/` `/STOP/`}}
<p>
This works, but there is a bug. If the call to os.Create fails, the
function will return without closing the source file. This can be easily
remedied by putting a call to src.Close() before the second return statement,
but if the function were more complex the problem might not be so easily
noticed and resolved. By introducing defer statements we can ensure that the
files are always closed:
</p>
{{code "progs/defer2.go" `/func CopyFile/` `/STOP/`}}
<p>
Defer statements allow us to think about closing each file right after opening
it, guaranteeing that, regardless of the number of return statements in the
function, the files <i>will</i> be closed.
</p>
<p>
The behavior of defer statements is straightforward and predictable. There are
three simple rules:
</p>
<p>
1. <i>A deferred function's arguments are evaluated when the defer statement is
evaluated.</i>
</p>
<p>
In this example, the expression "i" is evaluated when the Println call is
deferred. The deferred call will print "0" after the function returns.
</p>
{{code "progs/defer.go" `/func a/` `/STOP/`}}
<p>
2. <i>Deferred function calls are executed in Last In First Out order
</i>after<i> the surrounding function returns.</i>
</p>
<p>
This function prints "3210":
</p>
{{code "progs/defer.go" `/func b/` `/STOP/`}}
<p>
3. <i>Deferred functions may read and assign to the returning function's named
return values.</i>
</p>
<p>
In this example, a deferred function increments the return value i <i>after</i>
the surrounding function returns. Thus, this function returns 2:
</p>
{{code "progs/defer.go" `/func c/` `/STOP/`}}
<p>
This is convenient for modifying the error return value of a function; we will
see an example of this shortly.
</p>
<p>
<b>Panic</b> is a built-in function that stops the ordinary flow of control and
begins <i>panicking</i>. When the function F calls panic, execution of F stops,
any deferred functions in F are executed normally, and then F returns to its
caller. To the caller, F then behaves like a call to panic. The process
continues up the stack until all functions in the current goroutine have
returned, at which point the program crashes. Panics can be initiated by
invoking panic directly. They can also be caused by runtime errors, such as
out-of-bounds array accesses.
</p>
<p>
<b>Recover</b> is a built-in function that regains control of a panicking
goroutine. Recover is only useful inside deferred functions. During normal
execution, a call to recover will return nil and have no other effect. If the
current goroutine is panicking, a call to recover will capture the value given
to panic and resume normal execution.
</p>
<p>
Here's an example program that demonstrates the mechanics of panic and defer:
</p>
{{code "progs/defer2.go" `/package main/` `/STOP/`}}
<p>
The function g takes the int i, and panics if i is greater than 3, or else it
calls itself with the argument i+1. The function f defers a function that calls
recover and prints the recovered value (if it is non-nil). Try to picture what
the output of this program might be before reading on.
</p>
<p>
The program will output:
</p>
<pre>Calling g.
Printing in g 0
Printing in g 1
Printing in g 2
Printing in g 3
Panicking!
Defer in g 3
Defer in g 2
Defer in g 1
Defer in g 0
Recovered in f 4
Returned normally from f.</pre>
<p>
If we remove the deferred function from f the panic is not recovered and
reaches the top of the goroutine's call stack, terminating the program. This
modified program will output:
</p>
<pre>Calling g.
Printing in g 0
Printing in g 1
Printing in g 2
Printing in g 3
Panicking!
Defer in g 3
Defer in g 2
Defer in g 1
Defer in g 0
panic: 4
panic PC=0x2a9cd8
[stack trace omitted]</pre>
<p>
For a real-world example of <b>panic</b> and <b>recover</b>, see the
<a href="/pkg/encoding/json/">json package</a> from the Go standard library.
It decodes JSON-encoded data with a set of recursive functions.
When malformed JSON is encountered, the parser calls panic to unwind the
stack to the top-level function call, which recovers from the panic and returns
an appropriate error value (see the 'error' and 'unmarshal' functions in
<a href="/src/pkg/encoding/json/decode.go">decode.go</a>).
</p>
<p>
The convention in the Go libraries is that even when a package uses panic
internally, its external API still presents explicit error return values.
</p>
<p>
Other uses of <b>defer</b> (beyond the file.Close() example given earlier)
include releasing a mutex:
</p>
<pre>mu.Lock()
defer mu.Unlock()</pre>
<p>
printing a footer:
</p>
<pre>printHeader()
defer printFooter()</pre>
<p>
and more.
</p>
<p>
In summary, the defer statement (with or without panic and recover) provides an
unusual and powerful mechanism for control flow. It can be used to model a
number of features implemented by special-purpose structures in other
programming languages. Try it out.
</p>

View File

@ -1,10 +1,7 @@
<!--{
"Title": "Error Handling and Go"
"Title": "Error Handling and Go",
"Template": true
}-->
<!--
DO NOT EDIT: created by
tmpltohtml articles/error_handling.tmpl
-->
<p>
If you have written any Go code you have probably encountered the built-in
@ -13,20 +10,14 @@ indicate an abnormal state. For example, the <code>os.Open</code> function
returns a non-nil <code>error</code> value when it fails to open a file.
</p>
<pre><!--{{code "progs/error.go" `/func Open/`}}
-->func Open(name string) (file *File, err error)</pre>
{{code "/doc/progs/error.go" `/func Open/`}}
<p>
The following code uses <code>os.Open</code> to open a file. If an error
occurs it calls <code>log.Fatal</code> to print the error message and stop.
</p>
<pre><!--{{code "progs/error.go" `/func openFile/` `/STOP/`}}
--> f, err := os.Open(&#34;filename.ext&#34;)
if err != nil {
log.Fatal(err)
}
// do something with the open *File f</pre>
{{code "/doc/progs/error.go" `/func openFile/` `/STOP/`}}
<p>
You can get a lot done in Go knowing just this about the <code>error</code>
@ -59,15 +50,7 @@ The most commonly-used <code>error</code> implementation is the
<a href="/pkg/errors/">errors</a> package's unexported <code>errorString</code> type.
</p>
<pre><!--{{code "progs/error.go" `/errorString/` `/STOP/`}}
-->// errorString is a trivial implementation of error.
type errorString struct {
s string
}
func (e *errorString) Error() string {
return e.s
}</pre>
{{code "/doc/progs/error.go" `/errorString/` `/STOP/`}}
<p>
You can construct one of these values with the <code>errors.New</code>
@ -75,23 +58,13 @@ function. It takes a string that it converts to an <code>errors.errorString</cod
and returns as an <code>error</code> value.
</p>
<pre><!--{{code "progs/error.go" `/New/` `/STOP/`}}
-->// New returns an error that formats as the given text.
func New(text string) error {
return &amp;errorString{text}
}</pre>
{{code "/doc/progs/error.go" `/New/` `/STOP/`}}
<p>
Here's how you might use <code>errors.New</code>:
</p>
<pre><!--{{code "progs/error.go" `/func Sqrt/` `/STOP/`}}
-->func Sqrt(f float64) (float64, error) {
if f &lt; 0 {
return 0, errors.New(&#34;math: square root of negative number&#34;)
}
// implementation
}</pre>
{{code "/doc/progs/error.go" `/func Sqrt/` `/STOP/`}}
<p>
A caller passing a negative argument to <code>Sqrt</code> receives a non-nil
@ -101,11 +74,7 @@ A caller passing a negative argument to <code>Sqrt</code> receives a non-nil
<code>Error</code> method, or by just printing it:
</p>
<pre><!--{{code "progs/error.go" `/func printErr/` `/STOP/`}}
--> f, err := Sqrt(-1)
if err != nil {
fmt.Println(err)
}</pre>
{{code "/doc/progs/error.go" `/func printErr/` `/STOP/`}}
<p>
The <a href="/pkg/fmt/">fmt</a> package formats an <code>error</code> value
@ -126,10 +95,7 @@ rules and returns it as an <code>error</code> created by
<code>errors.New</code>.
</p>
<pre><!--{{code "progs/error.go" `/fmtError/` `/STOP/`}}
--> if f &lt; 0 {
return 0, fmt.Errorf(&#34;math: square root of negative number %g&#34;, f)
}</pre>
{{code "/doc/progs/error.go" `/fmtError/` `/STOP/`}}
<p>
In many cases <code>fmt.Errorf</code> is good enough, but since
@ -143,12 +109,7 @@ argument passed to <code>Sqrt</code>. We can enable that by defining a new
error implementation instead of using <code>errors.errorString</code>:
</p>
<pre><!--{{code "progs/error.go" `/type NegativeSqrtError/` `/STOP/`}}
-->type NegativeSqrtError float64
func (f NegativeSqrtError) Error() string {
return fmt.Sprintf(&#34;math: square root of negative number %g&#34;, float64(f))
}</pre>
{{code "/doc/progs/error.go" `/type NegativeSqrtError/` `/STOP/`}}
<p>
A sophisticated caller can then use a
@ -164,13 +125,7 @@ As another example, the <a href="/pkg/encoding/json/">json</a> package specifies
returns when it encounters a syntax error parsing a JSON blob.
</p>
<pre><!--{{code "progs/error.go" `/type SyntaxError/` `/STOP/`}}
-->type SyntaxError struct {
msg string // description of error
Offset int64 // error occurred after reading Offset bytes
}
func (e *SyntaxError) Error() string { return e.msg }</pre>
{{code "/doc/progs/error.go" `/type SyntaxError/` `/STOP/`}}
<p>
The <code>Offset</code> field isn't even shown in the default formatting of the
@ -178,14 +133,7 @@ error, but callers can use it to add file and line information to their error
messages:
</p>
<pre><!--{{code "progs/error.go" `/func decodeError/` `/STOP/`}}
--> if err := dec.Decode(&amp;val); err != nil {
if serr, ok := err.(*json.SyntaxError); ok {
line, col := findLine(f, serr.Offset)
return fmt.Errorf(&#34;%s:%d:%d: %v&#34;, f.Name(), line, col, err)
}
return err
}</pre>
{{code "/doc/progs/error.go" `/func decodeError/` `/STOP/`}}
<p>
(This is a slightly simplified version of some
@ -217,14 +165,7 @@ web crawler might sleep and retry when it encounters a temporary error and give
up otherwise.
</p>
<pre><!--{{code "progs/error.go" `/func netError/` `/STOP/`}}
--> if nerr, ok := err.(net.Error); ok &amp;&amp; nerr.Temporary() {
time.Sleep(1e9)
continue
}
if err != nil {
log.Fatal(err)
}</pre>
{{code "/doc/progs/error.go" `/func netError/` `/STOP/`}}
<p>
<b>Simplifying repetitive error handling</b>
@ -244,23 +185,7 @@ application with an HTTP handler that retrieves a record from the datastore and
formats it with a template.
</p>
<pre><!--{{code "progs/error2.go" `/func init/` `/STOP/`}}
-->func init() {
http.HandleFunc(&#34;/view&#34;, viewRecord)
}
func viewRecord(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
key := datastore.NewKey(c, &#34;Record&#34;, r.FormValue(&#34;id&#34;), 0, nil)
record := new(Record)
if err := datastore.Get(c, key, record); err != nil {
http.Error(w, err.Error(), 500)
return
}
if err := viewTemplate.Execute(w, record); err != nil {
http.Error(w, err.Error(), 500)
}
}</pre>
{{code "/doc/progs/error2.go" `/func init/` `/STOP/`}}
<p>
This function handles errors returned by the <code>datastore.Get</code>
@ -276,23 +201,13 @@ To reduce the repetition we can define our own HTTP <code>appHandler</code>
type that includes an <code>error</code> return value:
</p>
<pre><!--{{code "progs/error3.go" `/type appHandler/`}}
-->type appHandler func(http.ResponseWriter, *http.Request) error</pre>
{{code "/doc/progs/error3.go" `/type appHandler/`}}
<p>
Then we can change our <code>viewRecord</code> function to return errors:
</p>
<pre><!--{{code "progs/error3.go" `/func viewRecord/` `/STOP/`}}
-->func viewRecord(w http.ResponseWriter, r *http.Request) error {
c := appengine.NewContext(r)
key := datastore.NewKey(c, &#34;Record&#34;, r.FormValue(&#34;id&#34;), 0, nil)
record := new(Record)
if err := datastore.Get(c, key, record); err != nil {
return err
}
return viewTemplate.Execute(w, record)
}</pre>
{{code "/doc/progs/error3.go" `/func viewRecord/` `/STOP/`}}
<p>
This is simpler than the original version, but the <a
@ -302,12 +217,7 @@ To fix this we can implement the <code>http.Handler</code> interface's
<code>ServeHTTP</code> method on <code>appHandler</code>:
</p>
<pre><!--{{code "progs/error3.go" `/ServeHTTP/` `/STOP/`}}
-->func (fn appHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if err := fn(w, r); err != nil {
http.Error(w, err.Error(), 500)
}
}</pre>
{{code "/doc/progs/error3.go" `/ServeHTTP/` `/STOP/`}}
<p>
The <code>ServeHTTP</code> method calls the <code>appHandler</code> function
@ -323,10 +233,7 @@ Now when registering <code>viewRecord</code> with the http package we use the
<code>http.HandlerFunc</code>).
</p>
<pre><!--{{code "progs/error3.go" `/func init/` `/STOP/`}}
-->func init() {
http.Handle(&#34;/view&#34;, appHandler(viewRecord))
}</pre>
{{code "/doc/progs/error3.go" `/func init/` `/STOP/`}}
<p>
With this basic error handling infrastructure in place, we can make it more
@ -341,19 +248,13 @@ To do this we create an <code>appError</code> struct containing an
<code>error</code> and some other fields:
</p>
<pre><!--{{code "progs/error4.go" `/type appError/` `/STOP/`}}
-->type appError struct {
Error error
Message string
Code int
}</pre>
{{code "/doc/progs/error4.go" `/type appError/` `/STOP/`}}
<p>
Next we modify the appHandler type to return <code>*appError</code> values:
</p>
<pre><!--{{code "progs/error4.go" `/type appHandler/`}}
-->type appHandler func(http.ResponseWriter, *http.Request) *appError</pre>
{{code "/doc/progs/error4.go" `/type appHandler/`}}
<p>
(It's usually a mistake to pass back the concrete type of an error rather than
@ -369,33 +270,14 @@ status <code>Code</code> and log the full <code>Error</code> to the developer
console:
</p>
<pre><!--{{code "progs/error4.go" `/ServeHTTP/` `/STOP/`}}
-->func (fn appHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if e := fn(w, r); e != nil { // e is *appError, not os.Error.
c := appengine.NewContext(r)
c.Errorf(&#34;%v&#34;, e.Error)
http.Error(w, e.Message, e.Code)
}
}</pre>
{{code "/doc/progs/error4.go" `/ServeHTTP/` `/STOP/`}}
<p>
Finally, we update <code>viewRecord</code> to the new function signature and
have it return more context when it encounters an error:
</p>
<pre><!--{{code "progs/error4.go" `/func viewRecord/` `/STOP/`}}
-->func viewRecord(w http.ResponseWriter, r *http.Request) *appError {
c := appengine.NewContext(r)
key := datastore.NewKey(c, &#34;Record&#34;, r.FormValue(&#34;id&#34;), 0, nil)
record := new(Record)
if err := datastore.Get(c, key, record); err != nil {
return &amp;appError{err, &#34;Record not found&#34;, 404}
}
if err := viewTemplate.Execute(w, record); err != nil {
return &amp;appError{err, &#34;Can&#39;t display record&#34;, 500}
}
return nil
}</pre>
{{code "/doc/progs/error4.go" `/func viewRecord/` `/STOP/`}}
<p>
This version of <code>viewRecord</code> is the same length as the original, but

View File

@ -1,314 +0,0 @@
<!--{
"Title": "Error Handling and Go"
}-->
{{donotedit}}
<p>
If you have written any Go code you have probably encountered the built-in
<code>error</code> type. Go code uses <code>error</code> values to
indicate an abnormal state. For example, the <code>os.Open</code> function
returns a non-nil <code>error</code> value when it fails to open a file.
</p>
{{code "progs/error.go" `/func Open/`}}
<p>
The following code uses <code>os.Open</code> to open a file. If an error
occurs it calls <code>log.Fatal</code> to print the error message and stop.
</p>
{{code "progs/error.go" `/func openFile/` `/STOP/`}}
<p>
You can get a lot done in Go knowing just this about the <code>error</code>
type, but in this article we'll take a closer look at <code>error</code> and
discuss some good practices for error handling in Go.
</p>
<p>
<b>The error type</b>
</p>
<p>
The <code>error</code> type is an interface type. An <code>error</code>
variable represents any value that can describe itself as a string. Here is the
interface's declaration:
</p>
<pre>type error interface {
Error() string
}</pre>
<p>
The <code>error</code> type, as with all built in types, is
<a href="/doc/go_spec.html#Predeclared_identifiers">predeclared</a> in the
<a href="/doc/go_spec.html#Blocks">universe block</a>.
</p>
<p>
The most commonly-used <code>error</code> implementation is the
<a href="/pkg/errors/">errors</a> package's unexported <code>errorString</code> type.
</p>
{{code "progs/error.go" `/errorString/` `/STOP/`}}
<p>
You can construct one of these values with the <code>errors.New</code>
function. It takes a string that it converts to an <code>errors.errorString</code>
and returns as an <code>error</code> value.
</p>
{{code "progs/error.go" `/New/` `/STOP/`}}
<p>
Here's how you might use <code>errors.New</code>:
</p>
{{code "progs/error.go" `/func Sqrt/` `/STOP/`}}
<p>
A caller passing a negative argument to <code>Sqrt</code> receives a non-nil
<code>error</code> value (whose concrete representation is an
<code>errors.errorString</code> value). The caller can access the error string
("math: square root of...") by calling the <code>error</code>'s
<code>Error</code> method, or by just printing it:
</p>
{{code "progs/error.go" `/func printErr/` `/STOP/`}}
<p>
The <a href="/pkg/fmt/">fmt</a> package formats an <code>error</code> value
by calling its <code>Error() string</code> method.
</p>
<p>
It is the error implementation's responsibility to summarize the context.
The error returned by <code>os.Open</code> formats as "open /etc/passwd:
permission denied," not just "permission denied." The error returned by our
<code>Sqrt</code> is missing information about the invalid argument.
</p>
<p>
To add that information, a useful function is the <code>fmt</code> package's
<code>Errorf</code>. It formats a string according to <code>Printf</code>'s
rules and returns it as an <code>error</code> created by
<code>errors.New</code>.
</p>
{{code "progs/error.go" `/fmtError/` `/STOP/`}}
<p>
In many cases <code>fmt.Errorf</code> is good enough, but since
<code>error</code> is an interface, you can use arbitrary data structures as
error values, to allow callers to inspect the details of the error.
</p>
<p>
For instance, our hypothetical callers might want to recover the invalid
argument passed to <code>Sqrt</code>. We can enable that by defining a new
error implementation instead of using <code>errors.errorString</code>:
</p>
{{code "progs/error.go" `/type NegativeSqrtError/` `/STOP/`}}
<p>
A sophisticated caller can then use a
<a href="/doc/go_spec.html#Type_assertions">type assertion</a> to check for a
<code>NegativeSqrtError</code> and handle it specially, while callers that just
pass the error to <code>fmt.Println</code> or <code>log.Fatal</code> will see
no change in behavior.
</p>
<p>
As another example, the <a href="/pkg/encoding/json/">json</a> package specifies a
<code>SyntaxError</code> type that the <code>json.Decode</code> function
returns when it encounters a syntax error parsing a JSON blob.
</p>
{{code "progs/error.go" `/type SyntaxError/` `/STOP/`}}
<p>
The <code>Offset</code> field isn't even shown in the default formatting of the
error, but callers can use it to add file and line information to their error
messages:
</p>
{{code "progs/error.go" `/func decodeError/` `/STOP/`}}
<p>
(This is a slightly simplified version of some
<a href="http://camlistore.org/code/?p=camlistore.git;a=blob;f=lib/go/camli/jsonconfig/eval.go#l68">actual code</a>
from the <a href="http://camlistore.org">Camlistore</a> project.)
</p>
<p>
The <code>error</code> interface requires only a <code>Error</code> method;
specific error implementations might have additional methods. For instance, the
<a href="/pkg/net/">net</a> package returns errors of type
<code>error</code>, following the usual convention, but some of the error
implementations have additional methods defined by the <code>net.Error</code>
interface:
</p>
<pre>package net
type Error interface {
error
Timeout() bool // Is the error a timeout?
Temporary() bool // Is the error temporary?
}</pre>
<p>
Client code can test for a <code>net.Error</code> with a type assertion and
then distinguish transient network errors from permanent ones. For instance, a
web crawler might sleep and retry when it encounters a temporary error and give
up otherwise.
</p>
{{code "progs/error.go" `/func netError/` `/STOP/`}}
<p>
<b>Simplifying repetitive error handling</b>
</p>
<p>
In Go, error handling is important. The language's design and conventions
encourage you to explicitly check for errors where they occur (as distinct from
the convention in other languages of throwing exceptions and sometimes catching
them). In some cases this makes Go code verbose, but fortunately there are some
techniques you can use to minimize repetitive error handling.
</p>
<p>
Consider an <a href="http://code.google.com/appengine/docs/go/">App Engine</a>
application with an HTTP handler that retrieves a record from the datastore and
formats it with a template.
</p>
{{code "progs/error2.go" `/func init/` `/STOP/`}}
<p>
This function handles errors returned by the <code>datastore.Get</code>
function and <code>viewTemplate</code>'s <code>Execute</code> method. In both
cases, it presents a simple error message to the user with the HTTP status code
500 ("Internal Server Error"). This looks like a manageable amount of code, but
add some more HTTP handlers and you quickly end up with many copies of
identical error handling code.
</p>
<p>
To reduce the repetition we can define our own HTTP <code>appHandler</code>
type that includes an <code>error</code> return value:
</p>
{{code "progs/error3.go" `/type appHandler/`}}
<p>
Then we can change our <code>viewRecord</code> function to return errors:
</p>
{{code "progs/error3.go" `/func viewRecord/` `/STOP/`}}
<p>
This is simpler than the original version, but the <a
href="/pkg/net/http/">http</a> package doesn't understand functions that return
<code>error</code>.
To fix this we can implement the <code>http.Handler</code> interface's
<code>ServeHTTP</code> method on <code>appHandler</code>:
</p>
{{code "progs/error3.go" `/ServeHTTP/` `/STOP/`}}
<p>
The <code>ServeHTTP</code> method calls the <code>appHandler</code> function
and displays the returned error (if any) to the user. Notice that the method's
receiver, <code>fn</code>, is a function. (Go can do that!) The method invokes
the function by calling the receiver in the expression <code>fn(w, r)</code>.
</p>
<p>
Now when registering <code>viewRecord</code> with the http package we use the
<code>Handle</code> function (instead of <code>HandleFunc</code>) as
<code>appHandler</code> is an <code>http.Handler</code> (not an
<code>http.HandlerFunc</code>).
</p>
{{code "progs/error3.go" `/func init/` `/STOP/`}}
<p>
With this basic error handling infrastructure in place, we can make it more
user friendly. Rather than just displaying the error string, it would be better
to give the user a simple error message with an appropriate HTTP status code,
while logging the full error to the App Engine developer console for debugging
purposes.
</p>
<p>
To do this we create an <code>appError</code> struct containing an
<code>error</code> and some other fields:
</p>
{{code "progs/error4.go" `/type appError/` `/STOP/`}}
<p>
Next we modify the appHandler type to return <code>*appError</code> values:
</p>
{{code "progs/error4.go" `/type appHandler/`}}
<p>
(It's usually a mistake to pass back the concrete type of an error rather than
<code>error</code>, for reasons to be discussed in another article, but
it's the right thing to do here because <code>ServeHTTP</code> is the only
place that sees the value and uses its contents.)
</p>
<p>
And make <code>appHandler</code>'s <code>ServeHTTP</code> method display the
<code>appError</code>'s <code>Message</code> to the user with the correct HTTP
status <code>Code</code> and log the full <code>Error</code> to the developer
console:
</p>
{{code "progs/error4.go" `/ServeHTTP/` `/STOP/`}}
<p>
Finally, we update <code>viewRecord</code> to the new function signature and
have it return more context when it encounters an error:
</p>
{{code "progs/error4.go" `/func viewRecord/` `/STOP/`}}
<p>
This version of <code>viewRecord</code> is the same length as the original, but
now each of those lines has specific meaning and we are providing a friendlier
user experience.
</p>
<p>
It doesn't end there; we can further improve the error handling in our
application. Some ideas:
</p>
<ul>
<li>give the error handler a pretty HTML template,
<li>make debugging easier by writing the stack trace to the HTTP response when
the user is an administrator,
<li>write a constructor function for <code>appError</code> that stores the
stack trace for easier debugging,
<li>recover from panics inside the <code>appHandler</code>, logging the error
to the console as "Critical," while telling the user "a serious error
has occurred." This is a nice touch to avoid exposing the user to inscrutable
error messages caused by programming errors.
See the <a href="defer_panic_recover.html">Defer, Panic, and Recover</a>
article for more details.
</ul>
<p>
<b>Conclusion</b>
</p>
<p>
Proper error handling is an essential requirement of good software. By
employing the techniques described in this post you should be able to write
more reliable and succinct Go code.
</p>

View File

@ -1,11 +1,7 @@
<!--{
"Title": "The Laws of Reflection"
"Title": "The Laws of Reflection",
"Template": true
}-->
<!--
DO NOT EDIT: created by
tmpltohtml articles/laws_of_reflection.tmpl
-->
<p>
Reflection in computing is the
@ -36,11 +32,7 @@ exactly one type known and fixed at compile time: <code>int</code>,
and so on. If we declare
</p>
<pre><!--{{code "progs/interface.go" `/type MyInt/` `/STOP/`}}
-->type MyInt int
var i int
var j MyInt</pre>
{{code "/doc/progs/interface.go" `/type MyInt/` `/STOP/`}}
<p>
then <code>i</code> has type <code>int</code> and <code>j</code>
@ -60,16 +52,7 @@ interface's methods. A well-known pair of examples is
"http://golang.org/pkg/io/">io package</a>:
</p>
<pre><!--{{code "progs/interface.go" `/// Reader/` `/STOP/`}}
-->// Reader is the interface that wraps the basic Read method.
type Reader interface {
Read(p []byte) (n int, err error)
}
// Writer is the interface that wraps the basic Write method.
type Writer interface {
Write(p []byte) (n int, err error)
}</pre>
{{code "/doc/progs/interface.go" `/// Reader/` `/STOP/`}}
<p>
Any type that implements a <code>Read</code> (or
@ -80,12 +63,7 @@ purposes of this discussion, that means that a variable of type
<code>Read</code> method:
</p>
<pre><!--{{code "progs/interface.go" `/func readers/` `/STOP/`}}
--> var r io.Reader
r = os.Stdin
r = bufio.NewReader(r)
r = new(bytes.Buffer)
// and so on</pre>
{{code "/doc/progs/interface.go" `/func readers/` `/STOP/`}}
<p>
It's important to be clear that whatever concrete value
@ -138,13 +116,7 @@ that implements the interface and the type describes the full type
of that item. For instance, after
</p>
<pre><!--{{code "progs/interface.go" `/func typeAssertions/` `/STOP/`}}
--> var r io.Reader
tty, err := os.OpenFile(&#34;/dev/tty&#34;, os.O_RDWR, 0)
if err != nil {
return nil, err
}
r = tty</pre>
{{code "/doc/progs/interface.go" `/func typeAssertions/` `/STOP/`}}
<p>
<code>r</code> contains, schematically, the (value, type) pair,
@ -156,9 +128,7 @@ the type information about that value. That's why we can do things
like this:
</p>
<pre><!--{{code "progs/interface.go" `/var w io.Writer/` `/STOP/`}}
--> var w io.Writer
w = r.(io.Writer)</pre>
{{code "/doc/progs/interface.go" `/var w io.Writer/` `/STOP/`}}
<p>
The expression in this assignment is a type assertion; what it
@ -176,9 +146,7 @@ methods.
Continuing, we can do this:
</p>
<pre><!--{{code "progs/interface.go" `/var empty interface{}/` `/STOP/`}}
--> var empty interface{}
empty = w</pre>
{{code "/doc/progs/interface.go" `/var empty interface{}/` `/STOP/`}}
<p>
and our empty interface value <code>e</code> will again contain
@ -232,18 +200,7 @@ now.)
Let's start with <code>TypeOf</code>:
</p>
<pre><!--{{code "progs/interface2.go" `/package main/` `/STOP main/`}}
-->package main
import (
&#34;fmt&#34;
&#34;reflect&#34;
)
func main() {
var x float64 = 3.4
fmt.Println(&#34;type:&#34;, reflect.TypeOf(x))
}</pre>
{{code "/doc/progs/interface2.go" `/package main/` `/STOP main/`}}
<p>
This program prints
@ -281,9 +238,7 @@ value (from here on we'll elide the boilerplate and focus just on
the executable code):
</p>
<pre><!--{{code "progs/interface2.go" `/var x/` `/STOP/`}}
--> var x float64 = 3.4
fmt.Println(&#34;type:&#34;, reflect.TypeOf(x))</pre>
{{code "/doc/progs/interface2.go" `/var x/` `/STOP/`}}
<p>
prints
@ -307,12 +262,7 @@ on. Also methods on <code>Value</code> with names like
<code>int64</code> and <code>float64</code>) stored inside:
</p>
<pre><!--{{code "progs/interface2.go" `/START f1/` `/STOP/`}}
--> var x float64 = 3.4
v := reflect.ValueOf(x)
fmt.Println(&#34;type:&#34;, v.Type())
fmt.Println(&#34;kind is float64:&#34;, v.Kind() == reflect.Float64)
fmt.Println(&#34;value:&#34;, v.Float())</pre>
{{code "/doc/progs/interface2.go" `/START f1/` `/STOP/`}}
<p>
prints
@ -342,12 +292,7 @@ instance. That is, the <code>Int</code> method of
necessary to convert to the actual type involved:
</p>
<pre><!--{{code "progs/interface2.go" `/START f2/` `/STOP/`}}
--> var x uint8 = &#39;x&#39;
v := reflect.ValueOf(x)
fmt.Println(&#34;type:&#34;, v.Type()) // uint8.
fmt.Println(&#34;kind is uint8: &#34;, v.Kind() == reflect.Uint8) // true.
x = uint8(v.Uint()) // v.Uint returns a uint64.</pre>
{{code "/doc/progs/interface2.go" `/START f2/` `/STOP/`}}
<p>
The second property is that the <code>Kind</code> of a reflection
@ -356,10 +301,7 @@ reflection object contains a value of a user-defined integer type,
as in
</p>
<pre><!--{{code "progs/interface2.go" `/START f3/` `/STOP/`}}
--> type MyInt int
var x MyInt = 7
v := reflect.ValueOf(x)</pre>
{{code "/doc/progs/interface2.go" `/START f3/` `/STOP/`}}
<p>
the <code>Kind</code> of <code>v</code> is still
@ -395,9 +337,7 @@ func (v Value) Interface() interface{}
As a consequence we can say
</p>
<pre><!--{{code "progs/interface2.go" `/START f3b/` `/STOP/`}}
--> y := v.Interface().(float64) // y will have type float64.
fmt.Println(y)</pre>
{{code "/doc/progs/interface2.go" `/START f3b/` `/STOP/`}}
<p>
to print the <code>float64</code> value represented by the
@ -415,8 +355,7 @@ the <code>Interface</code> method to the formatted print
routine:
</p>
<pre><!--{{code "progs/interface2.go" `/START f3c/` `/STOP/`}}
--> fmt.Println(v.Interface())</pre>
{{code "/doc/progs/interface2.go" `/START f3c/` `/STOP/`}}
<p>
(Why not <code>fmt.Println(v)</code>? Because <code>v</code> is a
@ -425,8 +364,7 @@ Since our value is a <code>float64</code>, we can even use a
floating-point format if we want:
</p>
<pre><!--{{code "progs/interface2.go" `/START f3d/` `/STOP/`}}
--> fmt.Printf(&#34;value is %7.1e\n&#34;, v.Interface())</pre>
{{code "/doc/progs/interface2.go" `/START f3d/` `/STOP/`}}
<p>
and get in this case
@ -467,10 +405,7 @@ enough to understand if we start from first principles.
Here is some code that does not work, but is worth studying.
</p>
<pre><!--{{code "progs/interface2.go" `/START f4/` `/STOP/`}}
--> var x float64 = 3.4
v := reflect.ValueOf(x)
v.SetFloat(7.1) // Error: will panic.</pre>
{{code "/doc/progs/interface2.go" `/START f4/` `/STOP/`}}
<p>
If you run this code, it will panic with the cryptic message
@ -492,10 +427,7 @@ The <code>CanSet</code> method of <code>Value</code> reports the
settability of a <code>Value</code>; in our case,
</p>
<pre><!--{{code "progs/interface2.go" `/START f5/` `/STOP/`}}
--> var x float64 = 3.4
v := reflect.ValueOf(x)
fmt.Println(&#34;settability of v:&#34;, v.CanSet())</pre>
{{code "/doc/progs/interface2.go" `/START f5/` `/STOP/`}}
<p>
prints
@ -518,9 +450,7 @@ determined by whether the reflection object holds the original
item. When we say
</p>
<pre><!--{{code "progs/interface2.go" `/START f6/` `/STOP/`}}
--> var x float64 = 3.4
v := reflect.ValueOf(x)</pre>
{{code "/doc/progs/interface2.go" `/START f6/` `/STOP/`}}
<p>
we pass a <em>copy</em> of <code>x</code> to
@ -530,8 +460,7 @@ argument to <code>reflect.ValueOf</code> is a <em>copy</em> of
statement
</p>
<pre><!--{{code "progs/interface2.go" `/START f6b/` `/STOP/`}}
--> v.SetFloat(7.1)</pre>
{{code "/doc/progs/interface2.go" `/START f6b/` `/STOP/`}}
<p>
were allowed to succeed, it would not update <code>x</code>, even
@ -577,11 +506,7 @@ and then create a reflection value that points to it, called
<code>p</code>.
</p>
<pre><!--{{code "progs/interface2.go" `/START f7/` `/STOP/`}}
--> var x float64 = 3.4
p := reflect.ValueOf(&amp;x) // Note: take the address of x.
fmt.Println(&#34;type of p:&#34;, p.Type())
fmt.Println(&#34;settability of p:&#34;, p.CanSet())</pre>
{{code "/doc/progs/interface2.go" `/START f7/` `/STOP/`}}
<p>
The output so far is
@ -601,9 +526,7 @@ and save the result in a reflection <code>Value</code> called
<code>v</code>:
</p>
<pre><!--{{code "progs/interface2.go" `/START f7b/` `/STOP/`}}
--> v := p.Elem()
fmt.Println(&#34;settability of v:&#34;, v.CanSet())</pre>
{{code "/doc/progs/interface2.go" `/START f7b/` `/STOP/`}}
<p>
Now <code>v</code> is a settable reflection object, as the output
@ -620,10 +543,7 @@ and since it represents <code>x</code>, we are finally able to use
<code>x</code>:
</p>
<pre><!--{{code "progs/interface2.go" `/START f7c/` `/STOP/`}}
--> v.SetFloat(7.1)
fmt.Println(v.Interface())
fmt.Println(x)</pre>
{{code "/doc/progs/interface2.go" `/START f7c/` `/STOP/`}}
<p>
The output, as expected, is
@ -664,19 +584,7 @@ but the fields themselves are regular <code>reflect.Value</code>
objects.
</p>
<pre><!--{{code "progs/interface2.go" `/START f8/` `/STOP/`}}
--> type T struct {
A int
B string
}
t := T{23, &#34;skidoo&#34;}
s := reflect.ValueOf(&amp;t).Elem()
typeOfT := s.Type()
for i := 0; i &lt; s.NumField(); i++ {
f := s.Field(i)
fmt.Printf(&#34;%d: %s %s = %v\n&#34;, i,
typeOfT.Field(i).Name, f.Type(), f.Interface())
}</pre>
{{code "/doc/progs/interface2.go" `/START f8/` `/STOP/`}}
<p>
The output of this program is
@ -699,10 +607,7 @@ Because <code>s</code> contains a settable reflection object, we
can modify the fields of the structure.
</p>
<pre><!--{{code "progs/interface2.go" `/START f8b/` `/STOP/`}}
--> s.Field(0).SetInt(77)
s.Field(1).SetString(&#34;Sunset Strip&#34;)
fmt.Println(&#34;t is now&#34;, t)</pre>
{{code "/doc/progs/interface2.go" `/START f8b/` `/STOP/`}}
<p>
And here's the result:
@ -746,4 +651,4 @@ sending and receiving on channels, allocating memory, using slices
and maps, calling methods and functions &mdash; but this post is
long enough. We'll cover some of those topics in a later
article.
</p>
</p>

View File

@ -1,654 +0,0 @@
<!--{
"Title": "The Laws of Reflection"
}-->
{{donotedit}}
<p>
Reflection in computing is the
ability of a program to examine its own structure, particularly
through types; it's a form of metaprogramming. It's also a great
source of confusion.
</p>
<p>
In this article we attempt to clarify things by explaining how
reflection works in Go. Each language's reflection model is
different (and many languages don't support it at all), but
this article is about Go, so for the rest of this article the word
"reflection" should be taken to mean "reflection in Go".
</p>
<p><b>Types and interfaces</b></p>
<p>
Because reflection builds on the type system, let's start with a
refresher about types in Go.
</p>
<p>
Go is statically typed. Every variable has a static type, that is,
exactly one type known and fixed at compile time: <code>int</code>,
<code>float32</code>, <code>*MyType</code>, <code>[]byte</code>,
and so on. If we declare
</p>
{{code "progs/interface.go" `/type MyInt/` `/STOP/`}}
<p>
then <code>i</code> has type <code>int</code> and <code>j</code>
has type <code>MyInt</code>. The variables <code>i</code> and
<code>j</code> have distinct static types and, although they have
the same underlying type, they cannot be assigned to one another
without a conversion.
</p>
<p>
One important category of type is interface types, which represent
fixed sets of methods. An interface variable can store any concrete
(non-interface) value as long as that value implements the
interface's methods. A well-known pair of examples is
<code>io.Reader</code> and <code>io.Writer</code>, the types
<code>Reader</code> and <code>Writer</code> from the <a href=
"http://golang.org/pkg/io/">io package</a>:
</p>
{{code "progs/interface.go" `/// Reader/` `/STOP/`}}
<p>
Any type that implements a <code>Read</code> (or
<code>Write</code>) method with this signature is said to implement
<code>io.Reader</code> (or <code>io.Writer</code>). For the
purposes of this discussion, that means that a variable of type
<code>io.Reader</code> can hold any value whose type has a
<code>Read</code> method:
</p>
{{code "progs/interface.go" `/func readers/` `/STOP/`}}
<p>
It's important to be clear that whatever concrete value
<code>r</code> may hold, <code>r</code>'s type is always
<code>io.Reader</code>: Go is statically typed and the static type
of <code>r</code> is <code>io.Reader</code>.</p>
<p>
An extremely important example of an interface type is the empty
interface:
</p>
<pre>
interface{}
</pre>
<p>
It represents the empty set of methods and is satisfied by any
value at all, since any value has zero or more methods.
</p>
<p>
Some people say that Go's interfaces are dynamically typed, but
that is misleading. They are statically typed: a variable of
interface type always has the same static type, and even though at
run time the value stored in the interface variable may change
type, that value will always satisfy the interface.
</p>
<p>
We need to be precise about all this because reflection and
interfaces are closely related.
</p>
<p><b>The representation of an interface</b></p>
<p>
Russ Cox has written a <a href=
"http://research.swtch.com/2009/12/go-data-structures-interfaces.html">
detailed blog post</a> about the representation of interface values
in Go. It's not necessary to repeat the full story here, but a
simplified summary is in order.
</p>
<p>
A variable of interface type stores a pair: the concrete value
assigned to the variable, and that value's type descriptor.
To be more precise, the value is the underlying concrete data item
that implements the interface and the type describes the full type
of that item. For instance, after
</p>
{{code "progs/interface.go" `/func typeAssertions/` `/STOP/`}}
<p>
<code>r</code> contains, schematically, the (value, type) pair,
(<code>tty</code>, <code>*os.File</code>). Notice that the type
<code>*os.File</code> implements methods other than
<code>Read</code>; even though the interface value provides access
only to the <code>Read</code> method, the value inside carries all
the type information about that value. That's why we can do things
like this:
</p>
{{code "progs/interface.go" `/var w io.Writer/` `/STOP/`}}
<p>
The expression in this assignment is a type assertion; what it
asserts is that the item inside <code>r</code> also implements
<code>io.Writer</code>, and so we can assign it to <code>w</code>.
After the assignment, <code>w</code> will contain the pair
(<code>tty</code>, <code>*os.File</code>). That's the same pair as
was held in <code>r</code>. The static type of the interface
determines what methods may be invoked with an interface variable,
even though the concrete value inside may have a larger set of
methods.
</p>
<p>
Continuing, we can do this:
</p>
{{code "progs/interface.go" `/var empty interface{}/` `/STOP/`}}
<p>
and our empty interface value <code>e</code> will again contain
that same pair, (<code>tty</code>, <code>*os.File</code>). That's
handy: an empty interface can hold any value and contains all the
information we could ever need about that value.
</p>
<p>
(We don't need a type assertion here because it's known statically
that <code>w</code> satisfies the empty interface. In the example
where we moved a value from a <code>Reader</code> to a
<code>Writer</code>, we needed to be explicit and use a type
assertion because <code>Writer</code>'s methods are not a
subset of <code>Reader</code>'s.)
</p>
<p>
One important detail is that the pair inside an interface always
has the form (value, concrete type) and cannot have the form
(value, interface type). Interfaces do not hold interface
values.
</p>
<p>
Now we're ready to reflect.
</p>
<p><b>The first law of reflection</b></p>
<p><b>1. Reflection goes from interface value to reflection object.</b></p>
<p>
At the basic level, reflection is just a mechanism to examine the
type and value pair stored inside an interface variable. To get
started, there are two types we need to know about in
<a href="http://golang.org/pkg/reflect">package reflect</a>:
<a href="http://golang.org/pkg/reflect/#Type">Type</a> and
<a href="http://golang.org/pkg/reflect/#Value">Value</a>. Those two types
give access to the contents of an interface variable, and two
simple functions, called <code>reflect.TypeOf</code> and
<code>reflect.ValueOf</code>, retrieve <code>reflect.Type</code>
and <code>reflect.Value</code> pieces out of an interface value.
(Also, from the <code>reflect.Value</code> it's easy to get
to the <code>reflect.Type</code>, but let's keep the
<code>Value</code> and <code>Type</code> concepts separate for
now.)
</p>
<p>
Let's start with <code>TypeOf</code>:
</p>
{{code "progs/interface2.go" `/package main/` `/STOP main/`}}
<p>
This program prints
</p>
<pre>
type: float64
</pre>
<p>
You might be wondering where the interface is here, since the
program looks like it's passing the <code>float64</code>
variable <code>x</code>, not an interface value, to
<code>reflect.TypeOf</code>. But it's there; as <a href=
"http://golang.org/pkg/reflect/#Type.TypeOf">godoc reports</a>, the
signature of <code>reflect.TypeOf</code> includes an empty
interface:
</p>
<pre>
// TypeOf returns the reflection Type of the value in the interface{}.
func TypeOf(i interface{}) Type
</pre>
<p>
When we call <code>reflect.TypeOf(x)</code>, <code>x</code> is
first stored in an empty interface, which is then passed as the
argument; <code>reflect.TypeOf</code> unpacks that empty interface
to recover the type information.
</p>
<p>
The <code>reflect.ValueOf</code> function, of course, recovers the
value (from here on we'll elide the boilerplate and focus just on
the executable code):
</p>
{{code "progs/interface2.go" `/var x/` `/STOP/`}}
<p>
prints
</p>
<pre>
value: &lt;float64 Value&gt;
</pre>
<p>
Both <code>reflect.Type</code> and <code>reflect.Value</code> have
lots of methods to let us examine and manipulate them. One
important example is that <code>Value</code> has a
<code>Type</code> method that returns the <code>Type</code> of a
<code>reflect.Value</code>. Another is that both <code>Type</code>
and <code>Value</code> have a <code>Kind</code> method that returns
a constant indicating what sort of item is stored:
<code>Uint</code>, <code>Float64</code>, <code>Slice</code>, and so
on. Also methods on <code>Value</code> with names like
<code>Int</code> and <code>Float</code> let us grab values (as
<code>int64</code> and <code>float64</code>) stored inside:
</p>
{{code "progs/interface2.go" `/START f1/` `/STOP/`}}
<p>
prints
</p>
<pre>
type: float64
kind is float64: true
value: 3.4
</pre>
<p>
There are also methods like <code>SetInt</code> and
<code>SetFloat</code> but to use them we need to understand
settability, the subject of the third law of reflection, discussed
below.
</p>
<p>
The reflection library has a couple of properties worth singling
out. First, to keep the API simple, the "getter" and "setter"
methods of <code>Value</code> operate on the largest type that can
hold the value: <code>int64</code> for all the signed integers, for
instance. That is, the <code>Int</code> method of
<code>Value</code> returns an <code>int64</code> and the
<code>SetInt</code> value takes an <code>int64</code>; it may be
necessary to convert to the actual type involved:
</p>
{{code "progs/interface2.go" `/START f2/` `/STOP/`}}
<p>
The second property is that the <code>Kind</code> of a reflection
object describes the underlying type, not the static type. If a
reflection object contains a value of a user-defined integer type,
as in
</p>
{{code "progs/interface2.go" `/START f3/` `/STOP/`}}
<p>
the <code>Kind</code> of <code>v</code> is still
<code>reflect.Int</code>, even though the static type of
<code>x</code> is <code>MyInt</code>, not <code>int</code>. In
other words, the <code>Kind</code> cannot discriminate an int from
a <code>MyInt</code> even though the <code>Type</code> can.
</p>
<p><b>The second law of reflection</b></p>
<p><b>2. Reflection goes from reflection object to interface
value.</b></p>
<p>
Like physical reflection, reflection in Go generates its own
inverse.
</p>
<p>
Given a <code>reflect.Value</code> we can recover an interface
value using the <code>Interface</code> method; in effect the method
packs the type and value information back into an interface
representation and returns the result:
</p>
<pre>
// Interface returns v's value as an interface{}.
func (v Value) Interface() interface{}
</pre>
<p>
As a consequence we can say
</p>
{{code "progs/interface2.go" `/START f3b/` `/STOP/`}}
<p>
to print the <code>float64</code> value represented by the
reflection object <code>v</code>.
</p>
<p>
We can do even better, though. The arguments to
<code>fmt.Println</code>, <code>fmt.Printf</code> and so on are all
passed as empty interface values, which are then unpacked by the
<code>fmt</code> package internally just as we have been doing in
the previous examples. Therefore all it takes to print the contents
of a <code>reflect.Value</code> correctly is to pass the result of
the <code>Interface</code> method to the formatted print
routine:
</p>
{{code "progs/interface2.go" `/START f3c/` `/STOP/`}}
<p>
(Why not <code>fmt.Println(v)</code>? Because <code>v</code> is a
<code>reflect.Value</code>; we want the concrete value it holds.)
Since our value is a <code>float64</code>, we can even use a
floating-point format if we want:
</p>
{{code "progs/interface2.go" `/START f3d/` `/STOP/`}}
<p>
and get in this case
</p>
<pre>
3.4e+00
</pre>
<p>
Again, there's no need to type-assert the result of
<code>v.Interface()</code> to <code>float64</code>; the empty
interface value has the concrete value's type information inside
and <code>Printf</code> will recover it.
</p>
<p>
In short, the <code>Interface</code> method is the inverse of the
<code>ValueOf</code> function, except that its result is always of
static type <code>interface{}</code>.
</p>
<p>
Reiterating: Reflection goes from interface values to reflection
objects and back again.
</p>
<p><b>The third law of reflection</b></p>
<p><b>3. To modify a reflection object, the value must be settable.</b></p>
<p>
The third law is the most subtle and confusing, but it's easy
enough to understand if we start from first principles.
</p>
<p>
Here is some code that does not work, but is worth studying.
</p>
{{code "progs/interface2.go" `/START f4/` `/STOP/`}}
<p>
If you run this code, it will panic with the cryptic message
</p>
<pre>
panic: reflect.Value.SetFloat using unaddressable value
</pre>
<p>
The problem is not that the value <code>7.1</code> is not
addressable; it's that <code>v</code> is not settable. Settability
is a property of a reflection <code>Value</code>, and not all
reflection <code>Values</code> have it.
</p>
<p>
The <code>CanSet</code> method of <code>Value</code> reports the
settability of a <code>Value</code>; in our case,
</p>
{{code "progs/interface2.go" `/START f5/` `/STOP/`}}
<p>
prints
</p>
<pre>
settability of v: false
</pre>
<p>
It is an error to call a <code>Set</code> method on an non-settable
<code>Value</code>. But what is settability?
</p>
<p>
Settability is a bit like addressability, but stricter. It's the
property that a reflection object can modify the actual storage
that was used to create the reflection object. Settability is
determined by whether the reflection object holds the original
item. When we say
</p>
{{code "progs/interface2.go" `/START f6/` `/STOP/`}}
<p>
we pass a <em>copy</em> of <code>x</code> to
<code>reflect.ValueOf</code>, so the interface value created as the
argument to <code>reflect.ValueOf</code> is a <em>copy</em> of
<code>x</code>, not <code>x</code> itself. Thus, if the
statement
</p>
{{code "progs/interface2.go" `/START f6b/` `/STOP/`}}
<p>
were allowed to succeed, it would not update <code>x</code>, even
though <code>v</code> looks like it was created from
<code>x</code>. Instead, it would update the copy of <code>x</code>
stored inside the reflection value and <code>x</code> itself would
be unaffected. That would be confusing and useless, so it is
illegal, and settability is the property used to avoid this
issue.
</p>
<p>
If this seems bizarre, it's not. It's actually a familiar situation
in unusual garb. Think of passing <code>x</code> to a
function:
</p>
<pre>
f(x)
</pre>
<p>
We would not expect <code>f</code> to be able to modify
<code>x</code> because we passed a copy of <code>x</code>'s value,
not <code>x</code> itself. If we want <code>f</code> to modify
<code>x</code> directly we must pass our function the address of
<code>x</code> (that is, a pointer to <code>x</code>):</p>
<p>
<code>f(&amp;x)</code>
</p>
<p>
This is straightforward and familiar, and reflection works the same
way. If we want to modify <code>x</code> by reflection, we must
give the reflection library a pointer to the value we want to
modify.
</p>
<p>
Let's do that. First we initialize <code>x</code> as usual
and then create a reflection value that points to it, called
<code>p</code>.
</p>
{{code "progs/interface2.go" `/START f7/` `/STOP/`}}
<p>
The output so far is
</p>
<pre>
type of p: *float64
settability of p: false
</pre>
<p>
The reflection object <code>p</code> isn't settable, but it's not
<code>p</code> we want to set, it's (in effect) <code>*p</code>. To
get to what <code>p</code> points to, we call the <code>Elem</code>
method of <code>Value</code>, which indirects through the pointer,
and save the result in a reflection <code>Value</code> called
<code>v</code>:
</p>
{{code "progs/interface2.go" `/START f7b/` `/STOP/`}}
<p>
Now <code>v</code> is a settable reflection object, as the output
demonstrates,
</p>
<pre>
settability of v: true
</pre>
<p>
and since it represents <code>x</code>, we are finally able to use
<code>v.SetFloat</code> to modify the value of
<code>x</code>:
</p>
{{code "progs/interface2.go" `/START f7c/` `/STOP/`}}
<p>
The output, as expected, is
</p>
<pre>
7.1
7.1
</pre>
<p>
Reflection can be hard to understand but it's doing exactly what
the language does, albeit through reflection <code>Types</code> and
<code>Values</code> that can disguise what's going on. Just keep in
mind that reflection Values need the address of something in order
to modify what they represent.
</p>
<p><b>Structs</b></p>
<p>
In our previous example <code>v</code> wasn't a pointer itself, it
was just derived from one. A common way for this situation to arise
is when using reflection to modify the fields of a structure. As
long as we have the address of the structure, we can modify its
fields.
</p>
<p>
Here's a simple example that analyzes a struct value,
<code>t</code>. We create the reflection object with the address of
the struct because we'll want to modify it later. Then we set
<code>typeOfT</code> to its type and iterate over the fields using
straightforward method calls (see
<a href="http://golang.org/pkg/reflect/">package reflect</a> for details).
Note that we extract the names of the fields from the struct type,
but the fields themselves are regular <code>reflect.Value</code>
objects.
</p>
{{code "progs/interface2.go" `/START f8/` `/STOP/`}}
<p>
The output of this program is
</p>
<pre>
0: A int = 23
1: B string = skidoo
</pre>
<p>
There's one more point about settability introduced in
passing here: the field names of <code>T</code> are upper case
(exported) because only exported fields of a struct are
settable.
</p>
<p>
Because <code>s</code> contains a settable reflection object, we
can modify the fields of the structure.
</p>
{{code "progs/interface2.go" `/START f8b/` `/STOP/`}}
<p>
And here's the result:
</p>
<pre>
t is now {77 Sunset Strip}
</pre>
<p>
If we modified the program so that <code>s</code> was created from
<code>t</code>, not <code>&amp;t</code>, the calls to
<code>SetInt</code> and <code>SetString</code> would fail as the
fields of <code>t</code> would not be settable.
</p>
<p><b>Conclusion</b></p>
<p>
Here again are the laws of reflection:
</p>
<ol>
<li>Reflection goes from interface value to reflection
object.</li>
<li>Reflection goes from reflection object to interface
value.</li>
<li>To modify a reflection object, the value must be settable.</li>
</ol>
<p>
Once you understand these laws reflection in Go becomes much easier
to use, although it remains subtle. It's a powerful tool that
should be used with care and avoided unless strictly
necessary.
</p>
<p>
There's plenty more to reflection that we haven't covered &mdash;
sending and receiving on channels, allocating memory, using slices
and maps, calling methods and functions &mdash; but this post is
long enough. We'll cover some of those topics in a later
article.
</p>

View File

@ -1,11 +1,7 @@
<!--{
"Title": "Slices: usage and internals"
"Title": "Slices: usage and internals",
"Template": true
}-->
<!--
DO NOT EDIT: created by
tmpltohtml articles/slices_usage_and_internals.tmpl
-->
<p>
Go's slice type provides a convenient and efficient means of working with
@ -326,20 +322,7 @@ appends byte elements to a slice of bytes, growing the slice if necessary, and
returns the updated slice value:
</p>
<pre><!--{{code "progs/slices.go" `/AppendByte/` `/STOP/`}}
-->func AppendByte(slice []byte, data ...byte) []byte {
m := len(slice)
n := m + len(data)
if n &gt; cap(slice) { // if necessary, reallocate
// allocate double what&#39;s needed, for future growth.
newSlice := make([]byte, (n+1)*2)
copy(newSlice, slice)
slice = newSlice
}
slice = slice[0:n]
copy(slice[m:n], data)
return slice
}</pre>
{{code "/doc/progs/slices.go" `/AppendByte/` `/STOP/`}}
<p>
One could use <code>AppendByte</code> like this:
@ -398,18 +381,7 @@ Since the zero value of a slice (<code>nil</code>) acts like a zero-length
slice, you can declare a slice variable and then append to it in a loop:
</p>
<pre><!--{{code "progs/slices.go" `/Filter/` `/STOP/`}}
-->// Filter returns a new slice holding only
// the elements of s that satisfy f()
func Filter(s []int, fn func(int) bool) []int {
var p []int // == nil
for _, i := range s {
if fn(i) {
p = append(p, i)
}
}
return p
}</pre>
{{code "/doc/progs/slices.go" `/Filter/` `/STOP/`}}
<p>
<b>A possible "gotcha"</b>
@ -428,13 +400,7 @@ searches it for the first group of consecutive numeric digits, returning them
as a new slice.
</p>
<pre><!--{{code "progs/slices.go" `/digit/` `/STOP/`}}
-->var digitRegexp = regexp.MustCompile(&#34;[0-9]+&#34;)
func FindDigits(filename string) []byte {
b, _ := ioutil.ReadFile(filename)
return digitRegexp.Find(b)
}</pre>
{{code "/doc/progs/slices.go" `/digit/` `/STOP/`}}
<p>
This code behaves as advertised, but the returned <code>[]byte</code> points
@ -449,14 +415,7 @@ To fix this problem one can copy the interesting data to a new slice before
returning it:
</p>
<pre><!--{{code "progs/slices.go" `/CopyDigits/` `/STOP/`}}
-->func CopyDigits(filename string) []byte {
b, _ := ioutil.ReadFile(filename)
b = digitRegexp.Find(b)
c := make([]byte, len(b))
copy(c, b)
return c
}</pre>
{{code "/doc/progs/slices.go" `/CopyDigits/` `/STOP/`}}
<p>
A more concise version of this function could be constructed by using

View File

@ -1,438 +0,0 @@
<!--{
"Title": "Slices: usage and internals"
}-->
{{donotedit}}
<p>
Go's slice type provides a convenient and efficient means of working with
sequences of typed data. Slices are analogous to arrays in other languages, but
have some unusual properties. This article will look at what slices are and how
they are used.
</p>
<p>
<b>Arrays</b>
</p>
<p>
The slice type is an abstraction built on top of Go's array type, and so to
understand slices we must first understand arrays.
</p>
<p>
An array type definition specifies a length and an element type. For example,
the type <code>[4]int</code> represents an array of four integers. An array's
size is fixed; its length is part of its type (<code>[4]int</code> and
<code>[5]int</code> are distinct, incompatible types). Arrays can be indexed in
the usual way, so the expression <code>s[n]</code> accesses the <i>n</i>th
element:
</p>
<pre>
var a [4]int
a[0] = 1
i := a[0]
// i == 1
</pre>
<p>
Arrays do not need to be initialized explicitly; the zero value of an array is
a ready-to-use array whose elements are themselves zeroed:
</p>
<pre>
// a[2] == 0, the zero value of the int type
</pre>
<p>
The in-memory representation of <code>[4]int</code> is just four integer values laid out sequentially:
</p>
<p>
<img src="slice-array.png">
</p>
<p>
Go's arrays are values. An array variable denotes the entire array; it is not a
pointer to the first array element (as would be the case in C). This means
that when you assign or pass around an array value you will make a copy of its
contents. (To avoid the copy you could pass a <i>pointer</i> to the array, but
then that's a pointer to an array, not an array.) One way to think about arrays
is as a sort of struct but with indexed rather than named fields: a fixed-size
composite value.
</p>
<p>
An array literal can be specified like so:
</p>
<pre>
b := [2]string{"Penn", "Teller"}
</pre>
<p>
Or, you can have the compiler count the array elements for you:
</p>
<pre>
b := [...]string{"Penn", "Teller"}
</pre>
<p>
In both cases, the type of <code>b</code> is <code>[2]string</code>.
</p>
<p>
<b>Slices</b>
</p>
<p>
Arrays have their place, but they're a bit inflexible, so you don't see them
too often in Go code. Slices, though, are everywhere. They build on arrays to
provide great power and convenience.
</p>
<p>
The type specification for a slice is <code>[]T</code>, where <code>T</code> is
the type of the elements of the slice. Unlike an array type, a slice type has
no specified length.
</p>
<p>
A slice literal is declared just like an array literal, except you leave out
the element count:
</p>
<pre>
letters := []string{"a", "b", "c", "d"}
</pre>
<p>
A slice can be created with the built-in function called <code>make</code>,
which has the signature,
</p>
<pre>
func make([]T, len, cap) []T
</pre>
<p>
where T stands for the element type of the slice to be created. The
<code>make</code> function takes a type, a length, and an optional capacity.
When called, <code>make</code> allocates an array and returns a slice that
refers to that array.
</p>
<pre>
var s []byte
s = make([]byte, 5, 5)
// s == []byte{0, 0, 0, 0, 0}
</pre>
<p>
When the capacity argument is omitted, it defaults to the specified length.
Here's a more succinct version of the same code:
</p>
<pre>
s := make([]byte, 5)
</pre>
<p>
The length and capacity of a slice can be inspected using the built-in
<code>len</code> and <code>cap</code> functions.
</p>
<pre>
len(s) == 5
cap(s) == 5
</pre>
<p>
The next two sections discuss the relationship between length and capacity.
</p>
<p>
The zero value of a slice is <code>nil</code>. The <code>len</code> and
<code>cap</code> functions will both return 0 for a nil slice.
</p>
<p>
A slice can also be formed by "slicing" an existing slice or array. Slicing is
done by specifying a half-open range with two indices separated by a colon. For
example, the expression <code>b[1:4]</code> creates a slice including elements
1 through 3 of <code>b</code> (the indices of the resulting slice will be 0
through 2).
</p>
<pre>
b := []byte{'g', 'o', 'l', 'a', 'n', 'g'}
// b[1:4] == []byte{'o', 'l', 'a'}, sharing the same storage as b
</pre>
<p>
The start and end indices of a slice expression are optional; they default to zero and the slice's length respectively:
</p>
<pre>
// b[:2] == []byte{'g', 'o'}
// b[2:] == []byte{'l', 'a', 'n', 'g'}
// b[:] == b
</pre>
<p>
This is also the syntax to create a slice given an array:
</p>
<pre>
x := [3]string{"Лайка", "Белка", "Стрелка"}
s := x[:] // a slice referencing the storage of x
</pre>
<p>
<b>Slice internals</b>
</p>
<p>
A slice is a descriptor of an array segment. It consists of a pointer to the
array, the length of the segment, and its capacity (the maximum length of the
segment).
</p>
<p>
<img src="slice-struct.png">
</p>
<p>
Our variable <code>s</code>, created earlier by <code>make([]byte, 5)</code>,
is structured like this:
</p>
<p>
<img src="slice-1.png">
</p>
<p>
The length is the number of elements referred to by the slice. The capacity is
the number of elements in the underlying array (beginning at the element
referred to by the slice pointer). The distinction between length and capacity
will be made clear as we walk through the next few examples.
</p>
<p>
As we slice <code>s</code>, observe the changes in the slice data structure and
their relation to the underlying array:
</p>
<pre>
s = s[2:4]
</pre>
<p>
<img src="slice-2.png">
</p>
<p>
Slicing does not copy the slice's data. It creates a new slice value that
points to the original array. This makes slice operations as efficient as
manipulating array indices. Therefore, modifying the <i>elements</i> (not the
slice itself) of a re-slice modifies the elements of the original slice:
</p>
<pre>
d := []byte{'r', 'o', 'a', 'd'}
e := d[2:]
// e == []byte{'a', 'd'}
e[1] == 'm'
// e == []byte{'a', 'm'}
// d == []byte{'r', 'o', 'a', 'm'}
</pre>
<p>
Earlier we sliced <code>s</code> to a length shorter than its capacity. We can
grow s to its capacity by slicing it again:
</p>
<pre>
s = s[:cap(s)]
</pre>
<p>
<img src="slice-3.png">
</p>
<p>
A slice cannot be grown beyond its capacity. Attempting to do so will cause a
runtime panic, just as when indexing outside the bounds of a slice or array.
Similarly, slices cannot be re-sliced below zero to access earlier elements in
the array.
</p>
<p>
<b>Growing slices (the copy and append functions)</b>
</p>
<p>
To increase the capacity of a slice one must create a new, larger slice and
copy the contents of the original slice into it. This technique is how dynamic
array implementations from other languages work behind the scenes. The next
example doubles the capacity of <code>s</code> by making a new slice,
<code>t</code>, copying the contents of <code>s</code> into <code>t</code>, and
then assigning the slice value <code>t</code> to <code>s</code>:
</p>
<pre>
t := make([]byte, len(s), (cap(s)+1)*2) // +1 in case cap(s) == 0
for i := range s {
t[i] = s[i]
}
s = t
</pre>
<p>
The looping piece of this common operation is made easier by the built-in copy
function. As the name suggests, copy copies data from a source slice to a
destination slice. It returns the number of elements copied.
</p>
<pre>
func copy(dst, src []T) int
</pre>
<p>
The <code>copy</code> function supports copying between slices of different
lengths (it will copy only up to the smaller number of elements). In addition,
<code>copy</code> can handle source and destination slices that share the same
underlying array, handling overlapping slices correctly.
</p>
<p>
Using <code>copy</code>, we can simplify the code snippet above:
</p>
<pre>
t := make([]byte, len(s), (cap(s)+1)*2)
copy(t, s)
s = t
</pre>
<p>
A common operation is to append data to the end of a slice. This function
appends byte elements to a slice of bytes, growing the slice if necessary, and
returns the updated slice value:
</p>
{{code "progs/slices.go" `/AppendByte/` `/STOP/`}}
<p>
One could use <code>AppendByte</code> like this:
</p>
<pre>
p := []byte{2, 3, 5}
p = AppendByte(p, 7, 11, 13)
// p == []byte{2, 3, 5, 7, 11, 13}
</pre>
<p>
Functions like <code>AppendByte</code> are useful because they offer complete
control over the way the slice is grown. Depending on the characteristics of
the program, it may be desirable to allocate in smaller or larger chunks, or to
put a ceiling on the size of a reallocation.
</p>
<p>
But most programs don't need complete control, so Go provides a built-in
<code>append</code> function that's good for most purposes; it has the
signature
</p>
<pre>
func append(s []T, x ...T) []T
</pre>
<p>
The <code>append</code> function appends the elements <code>x</code> to the end
of the slice <code>s</code>, and grows the slice if a greater capacity is
needed.
</p>
<pre>
a := make([]int, 1)
// a == []int{0}
a = append(a, 1, 2, 3)
// a == []int{0, 1, 2, 3}
</pre>
<p>
To append one slice to another, use <code>...</code> to expand the second
argument to a list of arguments.
</p>
<pre>
a := []string{"John", "Paul"}
b := []string{"George", "Ringo", "Pete"}
a = append(a, b...) // equivalent to "append(a, b[0], b[1], b[2])"
// a == []string{"John", "Paul", "George", "Ringo", "Pete"}
</pre>
<p>
Since the zero value of a slice (<code>nil</code>) acts like a zero-length
slice, you can declare a slice variable and then append to it in a loop:
</p>
{{code "progs/slices.go" `/Filter/` `/STOP/`}}
<p>
<b>A possible "gotcha"</b>
</p>
<p>
As mentioned earlier, re-slicing a slice doesn't make a copy of the underlying
array. The full array will be kept in memory until it is no longer referenced.
Occasionally this can cause the program to hold all the data in memory when
only a small piece of it is needed.
</p>
<p>
For example, this <code>FindDigits</code> function loads a file into memory and
searches it for the first group of consecutive numeric digits, returning them
as a new slice.
</p>
{{code "progs/slices.go" `/digit/` `/STOP/`}}
<p>
This code behaves as advertised, but the returned <code>[]byte</code> points
into an array containing the entire file. Since the slice references the
original array, as long as the slice is kept around the garbage collector can't
release the array; the few useful bytes of the file keep the entire contents in
memory.
</p>
<p>
To fix this problem one can copy the interesting data to a new slice before
returning it:
</p>
{{code "progs/slices.go" `/CopyDigits/` `/STOP/`}}
<p>
A more concise version of this function could be constructed by using
<code>append</code>. This is left as an exercise for the reader.
</p>
<p>
<b>Further Reading</b>
</p>
<p>
<a href="/doc/effective_go.html">Effective Go</a> contains an
in-depth treatment of <a href="/doc/effective_go.html#slices">slices</a>
and <a href="/doc/effective_go.html#arrays">arrays</a>,
and the Go <a href="/doc/go_spec.html">language specification</a>
defines <a href="/doc/go_spec.html#Slice_types">slices</a> and their
<a href="/doc/go_spec.html#Length_and_capacity">associated</a>
<a href="/doc/go_spec.html#Making_slices_maps_and_channels">helper</a>
<a href="/doc/go_spec.html#Appending_and_copying_slices">functions</a>.
</p>

View File

@ -1,11 +1,7 @@
<!--{
"Title": "Effective Go"
"Title": "Effective Go",
"Template": true
}-->
<!--
DO NOT EDIT: created by
tmpltohtml effective_go.tmpl
-->
<h2 id="introduction">Introduction</h2>
@ -1693,47 +1689,13 @@ enumerator. Since <code>iota</code> can be part of an expression and
expressions can be implicitly repeated, it is easy to build intricate
sets of values.
</p>
<pre><!--{{code "progs/eff_bytesize.go" `/^type ByteSize/` `/^\)/`}}
-->type ByteSize float64
const (
_ = iota // ignore first value by assigning to blank identifier
KB ByteSize = 1 &lt;&lt; (10 * iota)
MB
GB
TB
PB
EB
ZB
YB
)</pre>
{{code "/doc/progs/eff_bytesize.go" `/^type ByteSize/` `/^\)/`}}
<p>
The ability to attach a method such as <code>String</code> to a
type makes it possible for such values to format themselves
automatically for printing, even as part of a general type.
</p>
<pre><!--{{code "progs/eff_bytesize.go" `/^func.*ByteSize.*String/` `/^}/`}}
-->func (b ByteSize) String() string {
switch {
case b &gt;= YB:
return fmt.Sprintf(&#34;%.2fYB&#34;, float64(b/YB))
case b &gt;= ZB:
return fmt.Sprintf(&#34;%.2fZB&#34;, float64(b/ZB))
case b &gt;= EB:
return fmt.Sprintf(&#34;%.2fEB&#34;, float64(b/EB))
case b &gt;= PB:
return fmt.Sprintf(&#34;%.2fPB&#34;, float64(b/PB))
case b &gt;= TB:
return fmt.Sprintf(&#34;%.2fTB&#34;, float64(b/TB))
case b &gt;= GB:
return fmt.Sprintf(&#34;%.2fGB&#34;, float64(b/GB))
case b &gt;= MB:
return fmt.Sprintf(&#34;%.2fMB&#34;, float64(b/MB))
case b &gt;= KB:
return fmt.Sprintf(&#34;%.2fKB&#34;, float64(b/KB))
}
return fmt.Sprintf(&#34;%.2fB&#34;, float64(b))
}</pre>
{{code "/doc/progs/eff_bytesize.go" `/^func.*ByteSize.*String/` `/^}/`}}
<p>
(The <code>float64</code> conversions prevent <code>Sprintf</code>
from recurring back through the <code>String</code> method for
@ -1879,32 +1841,7 @@ by the routines in package <code>sort</code> if it implements
and it could also have a custom formatter.
In this contrived example <code>Sequence</code> satisfies both.
</p>
<pre><!--{{code "progs/eff_sequence.go" `/^type/` "$"}}
-->type Sequence []int
// Methods required by sort.Interface.
func (s Sequence) Len() int {
return len(s)
}
func (s Sequence) Less(i, j int) bool {
return s[i] &lt; s[j]
}
func (s Sequence) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
// Method for printing - sorts the elements before printing.
func (s Sequence) String() string {
sort.Sort(s)
str := &#34;[&#34;
for i, elem := range s {
if i &gt; 0 {
str += &#34; &#34;
}
str += fmt.Sprint(elem)
}
return str + &#34;]&#34;
}</pre>
{{code "/doc/progs/eff_sequence.go" `/^type/` "$"}}
<h3 id="conversions">Conversions</h3>
@ -3010,53 +2947,7 @@ for instance, a URL, saving you typing the URL into the phone's tiny keyboard.
Here's the complete program.
An explanation follows.
</p>
<pre><!--{{code "progs/eff_qr.go"}}
-->package main
import (
&#34;flag&#34;
&#34;log&#34;
&#34;net/http&#34;
&#34;text/template&#34;
)
var addr = flag.String(&#34;addr&#34;, &#34;:1718&#34;, &#34;http service address&#34;) // Q=17, R=18
var templ = template.Must(template.New(&#34;qr&#34;).Parse(templateStr))
func main() {
flag.Parse()
http.Handle(&#34;/&#34;, http.HandlerFunc(QR))
err := http.ListenAndServe(*addr, nil)
if err != nil {
log.Fatal(&#34;ListenAndServe:&#34;, err)
}
}
func QR(w http.ResponseWriter, req *http.Request) {
templ.Execute(w, req.FormValue(&#34;s&#34;))
}
const templateStr = `
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;QR Link Generator&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
{{if .}}
&lt;img src=&#34;http://chart.apis.google.com/chart?chs=300x300&amp;cht=qr&amp;choe=UTF-8&amp;chl={{urlquery .}}&#34; /&gt;
&lt;br&gt;
{{html .}}
&lt;br&gt;
&lt;br&gt;
{{end}}
&lt;form action=&#34;/&#34; name=f method=&#34;GET&#34;&gt;&lt;input maxLength=1024 size=70
name=s value=&#34;&#34; title=&#34;Text to QR Encode&#34;&gt;&lt;input type=submit
value=&#34;Show QR&#34; name=qr&gt;
&lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;
`</pre>
{{code "/doc/progs/eff_qr.go"}}
<p>
The pieces up to <code>main</code> should be easy to follow.
The one flag sets a default HTTP port for our server. The template
@ -3082,13 +2973,13 @@ from data items passed to <code>templ.Execute</code>, in this case the
form value.
Within the template text (<code>templateStr</code>),
double-brace-delimited pieces denote template actions.
The piece from <code>{{if .}}</code>
to <code>{{end}}</code> executes only if the value of the current data item, called <code>.</code> (dot),
The piece from <code>{{html "{{if .}}"}}</code>
to <code>{{html "{{end}}"}}</code> executes only if the value of the current data item, called <code>.</code> (dot),
is non-empty.
That is, when the string is empty, this piece of the template is suppressed.
</p>
<p>
The snippet <code>{{urlquery .}}</code> says to process the data with the function
The snippet <code>{{html "{{urlquery .}}"}}</code> says to process the data with the function
<code>urlquery</code>, which sanitizes the query string
for safe display on the web page.
</p>

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +1,7 @@
<!--{
"Title": "Go 1 Release Notes"
"Title": "Go 1 Release Notes",
"Template": true
}-->
<!--
DO NOT EDIT: created by
tmpltohtml go1.tmpl
-->
<h2 id="introduction">Introduction to Go 1</h2>
@ -64,9 +60,7 @@ However, <code>append</code> did not provide a way to append a string to a <code
which is another common case.
</p>
<pre><!--{{code "progs/go1.go" `/greeting := ..byte/` `/append.*hello/`}}
--> greeting := []byte{}
greeting = append(greeting, []byte(&#34;hello &#34;)...)</pre>
{{code "/doc/progs/go1.go" `/greeting := ..byte/` `/append.*hello/`}}
<p>
By analogy with the similar property of <code>copy</code>, Go 1
@ -75,8 +69,7 @@ slice, reducing the friction between strings and byte slices.
The conversion is no longer necessary:
</p>
<pre><!--{{code "progs/go1.go" `/append.*world/`}}
--> greeting = append(greeting, &#34;world&#34;...)</pre>
{{code "/doc/progs/go1.go" `/append.*world/`}}
<p>
<em>Updating</em>:
@ -126,35 +119,7 @@ type specification for the elements' initializers if they are of pointer type.
All four of the initializations in this example are legal; the last one was illegal before Go 1.
</p>
<pre><!--{{code "progs/go1.go" `/type Date struct/` `/STOP/`}}
--> type Date struct {
month string
day int
}
// Struct values, fully qualified; always legal.
holiday1 := []Date{
Date{&#34;Feb&#34;, 14},
Date{&#34;Nov&#34;, 11},
Date{&#34;Dec&#34;, 25},
}
// Struct values, type name elided; always legal.
holiday2 := []Date{
{&#34;Feb&#34;, 14},
{&#34;Nov&#34;, 11},
{&#34;Dec&#34;, 25},
}
// Pointers, fully qualified, always legal.
holiday3 := []*Date{
&amp;Date{&#34;Feb&#34;, 14},
&amp;Date{&#34;Nov&#34;, 11},
&amp;Date{&#34;Dec&#34;, 25},
}
// Pointers, type name elided; legal in Go 1.
holiday4 := []*Date{
{&#34;Feb&#34;, 14},
{&#34;Nov&#34;, 11},
{&#34;Dec&#34;, 25},
}</pre>
{{code "/doc/progs/go1.go" `/type Date struct/` `/STOP/`}}
<p>
<em>Updating</em>:
@ -183,14 +148,7 @@ In Go 1, code that uses goroutines can be called from
without introducing a deadlock.
</p>
<pre><!--{{code "progs/go1.go" `/PackageGlobal/` `/^}/`}}
-->var PackageGlobal int
func init() {
c := make(chan int)
go initializationFunction(c)
PackageGlobal = &lt;-c
}</pre>
{{code "/doc/progs/go1.go" `/PackageGlobal/` `/^}/`}}
<p>
<em>Updating</em>:
@ -231,14 +189,7 @@ when appropriate. For instance, the functions <code>unicode.ToLower</code> and
relatives now take and return a <code>rune</code>.
</p>
<pre><!--{{code "progs/go1.go" `/STARTRUNE/` `/ENDRUNE/`}}
--> delta := &#39;δ&#39; // delta has type rune.
var DELTA rune
DELTA = unicode.ToUpper(delta)
epsilon := unicode.ToLower(DELTA + 1)
if epsilon != &#39;δ&#39;+1 {
log.Fatal(&#34;inconsistent casing for Greek&#34;)
}</pre>
{{code "/doc/progs/go1.go" `/STARTRUNE/` `/ENDRUNE/`}}
<p>
<em>Updating</em>:
@ -287,8 +238,7 @@ In Go 1, that syntax has gone; instead there is a new built-in
function, <code>delete</code>. The call
</p>
<pre><!--{{code "progs/go1.go" `/delete\(m, k\)/`}}
--> delete(m, k)</pre>
{{code "/doc/progs/go1.go" `/delete\(m, k\)/`}}
<p>
will delete the map entry retrieved by the expression <code>m[k]</code>.
@ -327,12 +277,7 @@ This change means that code that depends on iteration order is very likely to br
Just as important, it allows the map implementation to ensure better map balancing even when programs are using range loops to select an element from a map.
</p>
<pre><!--{{code "progs/go1.go" `/Sunday/` `/^ }/`}}
--> m := map[string]int{&#34;Sunday&#34;: 0, &#34;Monday&#34;: 1}
for name, value := range m {
// This loop should not assume Sunday will be visited first.
f(name, value)
}</pre>
{{code "/doc/progs/go1.go" `/Sunday/` `/^ }/`}}
<p>
<em>Updating</em>:
@ -367,17 +312,7 @@ proceed in left-to-right order.
These examples illustrate the behavior.
</p>
<pre><!--{{code "progs/go1.go" `/sa :=/` `/then sc.0. = 2/`}}
--> sa := []int{1, 2, 3}
i := 0
i, sa[i] = 1, 2 // sets i = 1, sa[0] = 2
sb := []int{1, 2, 3}
j := 0
sb[j], j = 2, 1 // sets sb[0] = 2, j = 1
sc := []int{1, 2, 3}
sc[0], sc[0] = 1, 2 // sets sc[0] = 1, then sc[0] = 2 (so sc[0] = 2 at end)</pre>
{{code "/doc/progs/go1.go" `/sa :=/` `/then sc.0. = 2/`}}
<p>
<em>Updating</em>:
@ -504,18 +439,7 @@ provided they are composed from elements for which equality is also defined,
using element-wise comparison.
</p>
<pre><!--{{code "progs/go1.go" `/type Day struct/` `/Printf/`}}
--> type Day struct {
long string
short string
}
Christmas := Day{&#34;Christmas&#34;, &#34;XMas&#34;}
Thanksgiving := Day{&#34;Thanksgiving&#34;, &#34;Turkey&#34;}
holiday := map[Day]bool{
Christmas: true,
Thanksgiving: true,
}
fmt.Printf(&#34;Christmas is a holiday: %t\n&#34;, holiday[Christmas])</pre>
{{code "/doc/progs/go1.go" `/type Day struct/` `/Printf/`}}
<p>
Second, Go 1 removes the definition of equality for function values,
@ -831,16 +755,7 @@ The <code>fmt</code> library automatically invokes <code>Error</code>, as it alr
does for <code>String</code>, for easy printing of error values.
</p>
<pre><!--{{code "progs/go1.go" `/START ERROR EXAMPLE/` `/END ERROR EXAMPLE/`}}
-->type SyntaxError struct {
File string
Line int
Message string
}
func (se *SyntaxError) Error() string {
return fmt.Sprintf(&#34;%s:%d: %s&#34;, se.File, se.Line, se.Message)
}</pre>
{{code "/doc/progs/go1.go" `/START ERROR EXAMPLE/` `/END ERROR EXAMPLE/`}}
<p>
All standard packages have been updated to use the new interface; the old <code>os.Error</code> is gone.
@ -858,8 +773,7 @@ func New(text string) error
to turn a string into an error. It replaces the old <code>os.NewError</code>.
</p>
<pre><!--{{code "progs/go1.go" `/ErrSyntax/`}}
--> var ErrSyntax = errors.New(&#34;syntax error&#34;)</pre>
{{code "/doc/progs/go1.go" `/ErrSyntax/`}}
<p>
<em>Updating</em>:
@ -949,17 +863,7 @@ returns a <code>time.Time</code> value rather than, in the old
API, an integer nanosecond count since the Unix epoch.
</p>
<pre><!--{{code "progs/go1.go" `/sleepUntil/` `/^}/`}}
-->// sleepUntil sleeps until the specified time. It returns immediately if it&#39;s too late.
func sleepUntil(wakeup time.Time) {
now := time.Now() // A Time.
if !wakeup.After(now) {
return
}
delta := wakeup.Sub(now) // A Duration.
fmt.Printf(&#34;Sleeping for %.3fs\n&#34;, delta.Seconds())
time.Sleep(delta)
}</pre>
{{code "/doc/progs/go1.go" `/sleepUntil/` `/^}/`}}
<p>
The new types, methods, and constants have been propagated through
@ -1196,8 +1100,7 @@ Values for such flags must be given units, just as <code>time.Duration</code>
formats them: <code>10s</code>, <code>1h30m</code>, etc.
</p>
<pre><!--{{code "progs/go1.go" `/timeout/`}}
-->var timeout = flag.Duration(&#34;timeout&#34;, 30*time.Second, &#34;how long to wait for completion&#34;)</pre>
{{code "/doc/progs/go1.go" `/timeout/`}}
<p>
<em>Updating</em>:
@ -1711,11 +1614,7 @@ and
<a href="/pkg/os/#IsPermission"><code>IsPermission</code></a>.
</p>
<pre><!--{{code "progs/go1.go" `/os\.Open/` `/}/`}}
--> f, err := os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
if os.IsExist(err) {
log.Printf(&#34;%s already exists&#34;, name)
}</pre>
{{code "/doc/progs/go1.go" `/os\.Open/` `/}/`}}
<p>
<em>Updating</em>:
@ -1781,21 +1680,7 @@ If a directory's contents are to be skipped,
the function should return the value <a href="/pkg/path/filepath/#variables"><code>filepath.SkipDir</code></a>
</p>
<pre><!--{{code "progs/go1.go" `/STARTWALK/` `/ENDWALK/`}}
--> markFn := func(path string, info os.FileInfo, err error) error {
if path == &#34;pictures&#34; { // Will skip walking of directory pictures and its contents.
return filepath.SkipDir
}
if err != nil {
return err
}
log.Println(path)
return nil
}
err := filepath.Walk(&#34;.&#34;, markFn)
if err != nil {
log.Fatal(err)
}</pre>
{{code "/doc/progs/go1.go" `/STARTWALK/` `/ENDWALK/`}}
<p>
<em>Updating</em>:
@ -1993,20 +1878,7 @@ In Go 1, <code>B</code> has new methods, analogous to those of <code>T</code>, e
logging and failure reporting.
</p>
<pre><!--{{code "progs/go1.go" `/func.*Benchmark/` `/^}/`}}
-->func BenchmarkSprintf(b *testing.B) {
// Verify correctness before running benchmark.
b.StopTimer()
got := fmt.Sprintf(&#34;%x&#34;, 23)
const expect = &#34;17&#34;
if expect != got {
b.Fatalf(&#34;expected %q; got %q&#34;, expect, got)
}
b.StartTimer()
for i := 0; i &lt; b.N; i++ {
fmt.Sprintf(&#34;%x&#34;, 23)
}
}</pre>
{{code "/doc/progs/go1.go" `/func.*Benchmark/` `/^}/`}}
<p>
<em>Updating</em>:

File diff suppressed because it is too large Load Diff

View File

@ -87,6 +87,9 @@ The flags are:
directory containing alternate template files; if set,
the directory may provide alternative template files
for the files in $GOROOT/lib/godoc
-url=path
print to standard output the data that would be served by
an HTTP request for path
-zip=""
zip file providing the file system to serve; disabled if empty

View File

@ -605,6 +605,23 @@ func serveHTMLDoc(w http.ResponseWriter, r *http.Request, abspath, relpath strin
log.Printf("decoding metadata %s: %v", relpath, err)
}
// evaluate as template if indicated
if meta.Template {
tmpl, err := template.New("main").Funcs(templateFuncs).Parse(string(src))
if err != nil {
log.Printf("parsing template %s: %v", relpath, err)
serveError(w, r, relpath, err)
return
}
var buf bytes.Buffer
if err := tmpl.Execute(&buf, nil); err != nil {
log.Printf("executing template %s: %v", relpath, err)
serveError(w, r, relpath, err)
return
}
src = buf.Bytes()
}
// if it's the language spec, add tags to EBNF productions
if strings.HasSuffix(abspath, "go_spec.html") {
var buf bytes.Buffer
@ -1177,6 +1194,7 @@ func search(w http.ResponseWriter, r *http.Request) {
type Metadata struct {
Title string
Subtitle string
Template bool // execute as template
Path string // canonical path for this page
filePath string // filesystem path relative to goroot
}

View File

@ -38,6 +38,7 @@ import (
"log"
"net/http"
_ "net/http/pprof" // to serve /debug/pprof/*
"net/url"
"os"
pathpkg "path"
"path/filepath"
@ -69,6 +70,7 @@ var (
// layout control
html = flag.Bool("html", false, "print HTML in command-line mode")
srcMode = flag.Bool("src", false, "print (exported) source in command-line mode")
urlFlag = flag.String("url", "", "print HTML for named URL")
// command-line searches
query = flag.Bool("q", false, "arguments are considered search queries")
@ -225,7 +227,7 @@ func main() {
flag.Parse()
// Check usage: either server and no args, command line and args, or index creation mode
if (*httpAddr != "") != (flag.NArg() == 0) && !*writeIndex {
if (*httpAddr != "" || *urlFlag != "") != (flag.NArg() == 0) && !*writeIndex {
usage()
}
@ -286,6 +288,44 @@ func main() {
return
}
// Print content that would be served at the URL *urlFlag.
if *urlFlag != "" {
registerPublicHandlers(http.DefaultServeMux)
// Try up to 10 fetches, following redirects.
urlstr := *urlFlag
for i := 0; i < 10; i++ {
// Prepare request.
u, err := url.Parse(urlstr)
if err != nil {
log.Fatal(err)
}
req := &http.Request{
URL: u,
}
// Invoke default HTTP handler to serve request
// to our buffering httpWriter.
w := &httpWriter{h: http.Header{}, code: 200}
http.DefaultServeMux.ServeHTTP(w, req)
// Return data, error, or follow redirect.
switch w.code {
case 200: // ok
os.Stdout.Write(w.Bytes())
return
case 301, 302, 303, 307: // redirect
redirect := w.h.Get("Location")
if redirect == "" {
log.Fatalf("HTTP %d without Location header", w.code)
}
urlstr = redirect
default:
log.Fatalf("HTTP error %d", w.code)
}
}
log.Fatalf("too many redirects")
}
if *httpAddr != "" {
// HTTP server mode.
var handler http.Handler = http.DefaultServeMux
@ -494,3 +534,13 @@ func main() {
log.Printf("packageText.Execute: %s", err)
}
}
// An httpWriter is an http.ResponseWriter writing to a bytes.Buffer.
type httpWriter struct {
bytes.Buffer
h http.Header
code int
}
func (w *httpWriter) Header() http.Header { return w.h }
func (w *httpWriter) WriteHeader(code int) { w.code = code }

View File

@ -2,6 +2,12 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Template support for writing HTML documents.
// Documents that include Template: true in their
// metadata are executed as input to text/template.
//
// This file defines functions for those templates to invoke.
// The template uses the function "code" to inject program
// source into the output by extracting code from files and
// injecting them as HTML-escaped <pre> blocks.
@ -26,52 +32,26 @@
package main
import (
"flag"
"fmt"
"io/ioutil"
"log"
"os"
"path/filepath"
"regexp"
"strings"
"text/template"
)
func Usage() {
fmt.Fprintf(os.Stderr, "usage: tmpltohtml file\n")
os.Exit(2)
}
// Functions in this file panic on error, but the panic is recovered
// to an error by 'code'.
var templateFuncs = template.FuncMap{
"code": code,
"donotedit": donotedit,
"code": code,
}
func main() {
flag.Usage = Usage
flag.Parse()
if len(flag.Args()) != 1 {
Usage()
}
// Read and parse the input.
name := flag.Arg(0)
tmpl := template.New(filepath.Base(name)).Funcs(templateFuncs)
if _, err := tmpl.ParseFiles(name); err != nil {
log.Fatal(err)
}
// Execute the template.
if err := tmpl.Execute(os.Stdout, 0); err != nil {
log.Fatal(err)
}
}
// contents reads a file by name and returns its contents as a string.
// contents reads and returns the content of the named file
// (from the virtual file system, so for example /doc refers to $GOROOT/doc).
func contents(name string) string {
file, err := ioutil.ReadFile(name)
file, err := ReadFile(fs, name)
if err != nil {
log.Fatal(err)
log.Panic(err)
}
return string(file)
}
@ -87,17 +67,18 @@ func format(arg interface{}) string {
}
return fmt.Sprintf("%q", arg)
default:
log.Fatalf("unrecognized argument: %v type %T", arg, arg)
log.Panicf("unrecognized argument: %v type %T", arg, arg)
}
return ""
}
func donotedit() string {
// No editing please.
return fmt.Sprintf("<!--\n DO NOT EDIT: created by\n tmpltohtml %s\n-->\n", flag.Args()[0])
}
func code(file string, arg ...interface{}) (s string, err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("%v", r)
}
}()
func code(file string, arg ...interface{}) (string, error) {
text := contents(file)
var command string
switch len(arg) {
@ -129,13 +110,13 @@ func parseArg(arg interface{}, file string, max int) (ival int, sval string, isI
switch n := arg.(type) {
case int:
if n <= 0 || n > max {
log.Fatalf("%q:%d is out of range", file, n)
log.Panicf("%q:%d is out of range", file, n)
}
return n, "", true
case string:
return 0, n, false
}
log.Fatalf("unrecognized argument %v type %T", arg, arg)
log.Panicf("unrecognized argument %v type %T", arg, arg)
return
}
@ -160,7 +141,7 @@ func multipleLines(file, text string, arg1, arg2 interface{}) string {
if !isInt2 {
line2 = match(file, line1, lines, pattern2)
} else if line2 < line1 {
log.Fatalf("lines out of order for %q: %d %d", text, line1, line2)
log.Panicf("lines out of order for %q: %d %d", text, line1, line2)
}
for k := line1 - 1; k < line2; k++ {
if strings.HasSuffix(lines[k], "OMIT\n") {
@ -177,7 +158,7 @@ func match(file string, start int, lines []string, pattern string) int {
// $ matches the end of the file.
if pattern == "$" {
if len(lines) == 0 {
log.Fatalf("%q: empty file", file)
log.Panicf("%q: empty file", file)
}
return len(lines)
}
@ -185,15 +166,15 @@ func match(file string, start int, lines []string, pattern string) int {
if len(pattern) > 2 && pattern[0] == '/' && pattern[len(pattern)-1] == '/' {
re, err := regexp.Compile(pattern[1 : len(pattern)-1])
if err != nil {
log.Fatal(err)
log.Panic(err)
}
for i := start; i < len(lines); i++ {
if re.MatchString(lines[i]) {
return i + 1
}
}
log.Fatalf("%s: no match for %#q", file, pattern)
log.Panicf("%s: no match for %#q", file, pattern)
}
log.Fatalf("unrecognized pattern: %q", pattern)
log.Panicf("unrecognized pattern: %q", pattern)
return 0
}