summaryrefslogtreecommitdiff
path: root/doc/go_faq.html
diff options
context:
space:
mode:
Diffstat (limited to 'doc/go_faq.html')
-rw-r--r--doc/go_faq.html262
1 files changed, 159 insertions, 103 deletions
diff --git a/doc/go_faq.html b/doc/go_faq.html
index aeed53795..93e1ea4ee 100644
--- a/doc/go_faq.html
+++ b/doc/go_faq.html
@@ -1,4 +1,6 @@
-<!-- FAQ -->
+<!--{
+ "Title": "FAQ"
+}-->
<h2 id="Origins">Origins</h2>
@@ -188,10 +190,11 @@ easier to understand what happens when things combine.
<p>
Yes. There are now several Go programs deployed in
-production inside Google. For instance, the server behind
-<a href="http://golang.org">http://golang.org</a> is a Go program;
-in fact it's just the <a href="/cmd/godoc"><code>godoc</code></a>
-document server running in a production configuration.
+production inside Google. A public example is the server behind
+<a href="http://golang.org">http://golang.org</a>.
+It's just the <a href="/cmd/godoc"><code>godoc</code></a>
+document server running in a production configuration on
+<a href="http://code.google.com/appengine/">Google App Engine</a>.
</p>
<h3 id="Do_Go_programs_link_with_Cpp_programs">
@@ -351,26 +354,6 @@ not familiar with the code.
</p>
<p>
-The same arguments apply to the use of <code>assert()</code> in test programs. Proper
-error handling means letting other tests run after one has failed, so
-that the person debugging the failure gets a complete picture of what is
-wrong. It is more useful for a test to report that
-<code>isPrime</code> gives the wrong answer for 2, 3, 5, and 7 (or for
-2, 4, 8, and 16) than to report that <code>isPrime</code> gives the wrong
-answer for 2 and therefore no more tests were run. The programmer who
-triggers the test failure may not be familiar with the code that fails.
-Time invested writing a good error message now pays off later when the
-test breaks.
-</p>
-
-<p>
-In testing, if the amount of extra code required to write
-good errors seems repetitive and overwhelming, it might work better as a
-table-driven test instead.
-Go has excellent support for data structure literals.
-</p>
-
-<p>
We understand that this is a point of contention. There are many things in
the Go language and libraries that differ from modern practices, simply
because we feel it's sometimes worth trying a different approach.
@@ -380,7 +363,7 @@ because we feel it's sometimes worth trying a different approach.
Why build concurrency on the ideas of CSP?</h3>
<p>
Concurrency and multi-threaded programming have a reputation
-for difficulty. We believe the problem is due partly to complex
+for difficulty. We believe this is due partly to complex
designs such as pthreads and partly to overemphasis on low-level details
such as mutexes, condition variables, and memory barriers.
Higher-level interfaces enable much simpler code, even if there are still
@@ -451,7 +434,9 @@ we believe is easy to use and in some ways more general. There are
also ways to embed types in other types to provide something
analogous&mdash;but not identical&mdash;to subclassing.
Moreover, methods in Go are more general than in C++ or Java:
-they can be defined for any sort of data, not just structs.
+they can be defined for any sort of data, even built-in types such
+as plain, &ldquo;unboxed&rdquo; integers.
+They are not restricted to structs (classes).
</p>
<p>
@@ -464,7 +449,7 @@ How do I get dynamic dispatch of methods?</h3>
<p>
The only way to have dynamically dispatched methods is through an
-interface. Methods on structs or other types are always resolved statically.
+interface. Methods on a struct or any other concrete type are always resolved statically.
</p>
<h3 id="inheritance">
@@ -496,8 +481,8 @@ It's possible to use these ideas to construct something analogous to
type-safe Unix pipes. For instance, see how <code>fmt.Fprintf</code>
enables formatted printing to any output, not just a file, or how the
<code>bufio</code> package can be completely separate from file I/O,
-or how the <code>crypto</code> packages stitch together block and
-stream ciphers. All these ideas stem from a single interface
+or how the <code>image</code> packages generate compressed
+image files. All these ideas stem from a single interface
(<code>io.Writer</code>) representing a single method
(<code>Write</code>). And that's only scratching the surface.
</p>
@@ -559,7 +544,7 @@ interface <code>I</code> by attempting an assignment:
<pre>
type T struct{}
-var _ I = T{}
+var _ I = T{} // Verify that T implements I.
</pre>
<p>
@@ -575,8 +560,8 @@ For example:
<pre>
type Fooer interface {
- Foo()
- ImplementsFooer()
+ Foo()
+ ImplementsFooer()
}
</pre>
@@ -608,7 +593,7 @@ itself with another value:
<pre>
type Equaler interface {
- Equal(Equaler) bool
+ Equal(Equaler) bool
}
</pre>
@@ -681,7 +666,7 @@ examples and also have them be statically checked.
Can I convert a []T to an []interface{}?</h3>
<p>
-Not directly because they do not have the same representation in memory.
+Not directly, because they do not have the same representation in memory.
It is necessary to copy the elements individually to the destination
slice. This example converts a slice of <code>int</code> to a slice of
<code>interface{}</code>:
@@ -691,7 +676,7 @@ slice. This example converts a slice of <code>int</code> to a slice of
t := []int{1, 2, 3, 4}
s := make([]interface{}, len(t))
for i, v := range t {
- s[i] = v
+ s[i] = v
}
</pre>
@@ -768,17 +753,22 @@ to write one but it will not be as convenient syntactically; this seems a reason
</p>
<h3 id="map_keys">
-Why don't maps allow structs and arrays as keys?</h3>
+Why don't maps allow slices as keys?</h3>
<p>
-Map lookup requires an equality operator, which structs and arrays do not implement.
+Map lookup requires an equality operator, which slices do not implement.
They don't implement equality because equality is not well defined on such types;
there are multiple considerations involving shallow vs. deep comparison, pointer vs.
-value comparison, how to deal with recursive structures, and so on.
-We may revisit this issue&mdash;and implementing equality for structs and arrays
+value comparison, how to deal with recursive types, and so on.
+We may revisit this issue&mdash;and implementing equality for slices
will not invalidate any existing programs&mdash;but without a clear idea of what
equality of structs and arrays should mean, it was simpler to leave it out for now.
</p>
+<p>
+In Go 1, equality is defined for structs and arrays, so such
+types can be used as map keys, but slices still do not have a definition of equality.
+</p>
+
<h3 id="references">
Why are maps, slices, and channels references while arrays are values?</h3>
<p>
@@ -841,14 +831,17 @@ for more information about how to proceed.
When are function parameters passed by value?</h3>
<p>
-Everything in Go is passed by value. A function always gets a copy of the
+As in all languages in the C family, everything in Go is passed by value.
+That is, a function always gets a copy of the
thing being passed, as if there were an assignment statement assigning the
-value to the parameter. For instance, copying a pointer value makes a copy of
-the pointer, not the data it points to.
+value to the parameter. For instance, passing an <code>int</code> value
+to a function makes a copy of the <code>int</code>, and passing a pointer
+value makes a copy of the pointer, but not the data it points to.
+(See the next section for a discussion of how this affects method receivers.)
</p>
<p>
-Map and slice values behave like pointers; they are descriptors that
+Map and slice values behave like pointers: they are descriptors that
contain pointers to the underlying map or slice data. Copying a map or
slice value doesn't copy the data it points to. Copying an interface value
makes a copy of the thing stored in the interface value. If the interface
@@ -946,6 +939,12 @@ floating-point numbers.
The default size of a floating-point constant is <code>float64</code>.
</p>
+<p>
+At the moment, all implementations use 32-bit ints, an essentially arbitrary decision.
+However, we expect that <code>int</code> will be increased to 64 bits on 64-bit
+architectures in a future release of Go.
+</p>
+
<h3 id="stack_or_heap">
How do I know whether a variable is allocated on the heap or the stack?</h3>
@@ -963,12 +962,15 @@ local to a function in that function's stack frame. However, if the
compiler cannot prove that the variable is not referenced after the
function returns, then the compiler must allocate the variable on the
garbage-collected heap to avoid dangling pointer errors.
+Also, if a local variable is very large, it might make more sense
+to store it on the heap rather than the stack.
</p>
<p>
-In the current compilers, the analysis is crude: if a variable has its address
-taken, that variable is allocated on the heap. We are working to improve this
-analysis so that more data is kept on the stack.
+In the current compilers, if a variable has its address taken, that variable
+is a candidate for allocation on the heap. However, a basic <em>escape
+analysis</em> recognizes some cases when such variables will not
+live past the return from the function and can reside on the stack.
</p>
<h2 id="Concurrency">Concurrency</h2>
@@ -1001,14 +1003,12 @@ See the <a href="/doc/codewalk/sharemem/">Share Memory By Communicating</a> code
Why doesn't my multi-goroutine program use multiple CPUs?</h3>
<p>
-Under the gc compilers you must set <code>GOMAXPROCS</code> to allow the
-run-time support to utilise more than one OS thread. Under <code>gccgo</code> an OS
-thread will be created for each goroutine, and <code>GOMAXPROCS</code> is
-effectively equal to the number of running goroutines.
+You must set <code>GOMAXPROCS</code> to allow the
+run-time support to utilize more than one OS thread.
</p>
<p>
-Programs that perform concurrent computation should benefit from an increase in
+Programs that perform parallel computation should benefit from an increase in
<code>GOMAXPROCS</code>. (See the <a
href="http://golang.org/pkg/runtime/#GOMAXPROCS"><code>runtime</code> package's
documentation</a>.)
@@ -1019,15 +1019,24 @@ Why does using <code>GOMAXPROCS</code> &gt; 1 sometimes make my program
slower?</h3>
<p>
-(This is specific to the gc compilers. See above.)
+It depends on the nature of your program.
+Problems that are intrinsically sequential cannot be sped up by adding
+more goroutines.
+Concurrency only becomes parallelism when the problem is
+intrinsically parallel.
</p>
<p>
-It depends on the nature of your program.
-Programs that contain several goroutines that spend a lot of time
-communicating on channels will experience performance degradation when using
-multiple OS threads. This is because of the significant context-switching
-penalty involved in sending data between threads.
+In practical terms, programs that spend more time
+communicating on channels than doing computation
+will experience performance degradation when using
+multiple OS threads.
+This is because sending data between threads involves switching
+contexts, which has significant cost.
+For instance, the <a href="/doc/go_spec.html#An_example_package">prime sieve example</a>
+from the Go specification has no significant parallelism although it launches many
+goroutines; increasing <code>GOMAXPROCS</code> is more likely to slow it down than
+to speed it up.
</p>
<p>
@@ -1075,7 +1084,7 @@ This is almost never the desired behavior.
</p>
<h3 id="closures_and_goroutines">
-Why am I confused by the way my closures behave as goroutines?</h3>
+What happens with closures running as goroutines?</h3>
<p>
Some confusion may arise when using closures with concurrency.
@@ -1084,29 +1093,30 @@ Consider the following program:
<pre>
func main() {
- done := make(chan bool)
-
- values := []string{ "a", "b", "c" }
- for _, v := range values {
- go func() {
- fmt.Println(v)
- done &lt;- true
- }()
- }
-
- // wait for all goroutines to complete before exiting
- for _ = range values {
- &lt;-done
- }
+ done := make(chan bool)
+
+ values := []string{ "a", "b", "c" }
+ for _, v := range values {
+ go func() {
+ fmt.Println(v)
+ done &lt;- true
+ }()
+ }
+
+ // wait for all goroutines to complete before exiting
+ for _ = range values {
+ &lt;-done
+ }
}
</pre>
<p>
One might mistakenly expect to see <code>a, b, c</code> as the output.
What you'll probably see instead is <code>c, c, c</code>. This is because
-each closure shares the same variable <code>v</code>. Each closure prints the
-value of <code>v</code> at the time <code>fmt.Println</code> is executed,
-rather than the value of <code>v</code> when the goroutine was launched.
+each iteration of the loop uses the same instance of the variable <code>v</code>, so
+each closure shares that single variable. When the closure runs, it prints the
+value of <code>v</code> at the time <code>fmt.Println</code> is executed,
+but <code>v</code> may have been modified since the goroutine was launched.
</p>
<p>
@@ -1115,12 +1125,12 @@ could modify the inner loop to read:
</p>
<pre>
- for _, v := range values {
- go func(<b>u</b> string) {
- fmt.Println(<b>u</b>)
- done &lt;- true
- }(<b>v</b>)
- }
+ for _, v := range values {
+ go func(<b>u</b> string) {
+ fmt.Println(<b>u</b>)
+ done &lt;- true
+ }(<b>v</b>)
+ }
</pre>
<p>
@@ -1141,9 +1151,9 @@ result:
<pre>
if expr {
- n = trueVal
+ n = trueVal
} else {
- n = falseVal
+ n = falseVal
}
</pre>
@@ -1186,6 +1196,45 @@ builds a test binary, and runs it.
<p>See the <a href="/doc/code.html">How to Write Go Code</a> document for more details.</p>
+<h3 id="testing_framework">
+Where is my favorite helper function for testing?</h3>
+
+<p>
+Go's standard <code>testing</code> package makes it easy to write unit tests, but it lacks
+features provided in other language's testing frameworks such as assertion functions.
+An <a href="#assertions">earlier section</a> of this document explained why Go
+doesn't have assertions, and
+the same arguments apply to the use of <code>assert</code> in tests.
+Proper error handling means letting other tests run after one has failed, so
+that the person debugging the failure gets a complete picture of what is
+wrong. It is more useful for a test to report that
+<code>isPrime</code> gives the wrong answer for 2, 3, 5, and 7 (or for
+2, 4, 8, and 16) than to report that <code>isPrime</code> gives the wrong
+answer for 2 and therefore no more tests were run. The programmer who
+triggers the test failure may not be familiar with the code that fails.
+Time invested writing a good error message now pays off later when the
+test breaks.
+</p>
+
+<p>
+A related point is that testing frameworks tend to develop into mini-languages
+of their own, with conditionals and controls and printing mechanisms,
+but Go already has all those capabilities; why recreate them?
+We'd rather write tests in Go; it's one fewer language to learn and the
+approach keeps the tests straightforward and easy to understand.
+</p>
+
+<p>
+If the amount of extra code required to write
+good errors seems repetitive and overwhelming, the test might work better if
+table-driven, iterating over a list of inputs and outputs defined
+in a data structure (Go has excellent support for data structure literals).
+The work to write a good test and good error messages will then be amortized over many
+test cases. The standard Go library is full of illustrative examples, such as in
+<a href="http://golang.org/src/pkg/fmt/fmt_test.go">the formatting
+tests for the <code>fmt</code> package</a>.
+</p>
+
<h2 id="Implementation">Implementation</h2>
@@ -1227,16 +1276,16 @@ it now. <code>Gccgo</code>'s run-time support uses <code>glibc</code>.
control; it is
compiled with a version of the Plan 9 C compiler that supports
segmented stacks for goroutines.
-Work is underway to provide the same stack management in
-<code>gccgo</code>.
+The <code>gccgo</code> compiler also implements segmented
+stacks, supported by recent modifications to its linker.
</p>
<h3 id="Why_is_my_trivial_program_such_a_large_binary">
Why is my trivial program such a large binary?</h3>
<p>
-The gc tool chain (<code>5l</code>, <code>6l</code>, and <code>8l</code>) only
-generate statically linked binaries. All Go binaries therefore include the Go
+The linkers in the gc tool chain (<code>5l</code>, <code>6l</code>, and <code>8l</code>)
+do static linking. All Go binaries therefore include the Go
run-time, along with the run-time type information necessary to support dynamic
type checks, reflection, and even panic-time stack traces.
</p>
@@ -1296,9 +1345,9 @@ import "unused"
var _ = unused.Item // TODO: Delete before committing!
func main() {
- debugData := debug.Profile()
- _ = debugData // Used only during debugging.
- ....
+ debugData := debug.Profile()
+ _ = debugData // Used only during debugging.
+ ....
}
</pre>
@@ -1312,18 +1361,21 @@ One of Go's design goals is to approach the performance of C for comparable
programs, yet on some benchmarks it does quite poorly, including several
in <a href="/test/bench/">test/bench</a>. The slowest depend on libraries
for which versions of comparable performance are not available in Go.
-For instance, pidigits depends on a multi-precision math package, and the C
+For instance, <a href="/test/bench/shootout/pidigits.go">pidigits.go</a>
+depends on a multi-precision math package, and the C
versions, unlike Go's, use <a href="http://gmplib.org/">GMP</a> (which is
written in optimized assembler).
-Benchmarks that depend on regular expressions (regex-dna, for instance) are
-essentially comparing Go's stopgap <a href="/pkg/regexp">regexp package</a> to
+Benchmarks that depend on regular expressions
+(<a href="/test/bench/shootout/regex-dna.go">regex-dna.go</a>, for instance) are
+essentially comparing Go's native <a href="/pkg/regexp">regexp package</a> to
mature, highly optimized regular expression libraries like PCRE.
</p>
<p>
Benchmark games are won by extensive tuning and the Go versions of most
of the benchmarks need attention. If you measure comparable C
-and Go programs (reverse-complement is one example), you'll see the two
+and Go programs
+(<a href="/test/bench/shootout/reverse-complement.go">reverse-complement.go</a> is one example), you'll see the two
languages are much closer in raw performance than this suite would
indicate.
</p>
@@ -1331,8 +1383,8 @@ indicate.
<p>
Still, there is room for improvement. The compilers are good but could be
better, many libraries need major performance work, and the garbage collector
-isn't fast enough yet (even if it were, taking care not to generate unnecessary
-garbage can have a huge effect).
+isn't fast enough yet. (Even if it were, taking care not to generate unnecessary
+garbage can have a huge effect.)
</p>
<p>
@@ -1367,13 +1419,13 @@ prefix <code>*</code> for pointers is an exception that proves the rule). In C,
the declaration
</p>
<pre>
- int* a, b;
+ int* a, b;
</pre>
<p>
declares <code>a</code> to be a pointer but not <code>b</code>; in Go
</p>
<pre>
- var a, b *int;
+ var a, b *int
</pre>
<p>
declares both to be pointers. This is clearer and more regular.
@@ -1381,11 +1433,11 @@ Also, the <code>:=</code> short declaration form argues that a full variable
declaration should present the same order as <code>:=</code> so
</p>
<pre>
- var a uint64 = 1;
+ var a uint64 = 1
</pre>
has the same effect as
<pre>
- a := uint64(1);
+ a := uint64(1)
</pre>
<p>
Parsing is also simplified by having a distinct grammar for types that
@@ -1464,8 +1516,7 @@ memory management. We feel it's critical to eliminate that
programmer overhead, and advances in garbage collection
technology in the last few years give us confidence that we can
implement it with low enough overhead and no significant
-latency. (The current implementation is a plain mark-and-sweep
-collector but a replacement is in the works.)
+latency.
</p>
<p>
@@ -1485,6 +1536,11 @@ simpler because they don't need to specify how memory is managed across them.
</p>
<p>
+The current implementation is a parallel mark-and-sweep
+collector but a future version might take a different approach.
+</p>
+
+<p>
On the topic of performance, keep in mind that Go gives the programmer
considerable control over memory layout and allocation, much more than
is typical in garbage-collected languages. A careful programmer can reduce