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

FAQ: update to Go 1.

R=adg, rsc, r
CC=golang-dev
https://golang.org/cl/5562051
This commit is contained in:
Rob Pike 2012-01-23 08:39:53 -08:00
parent 93c4e29605
commit fcfed1479e

View File

@ -190,10 +190,11 @@ easier to understand what happens when things combine.
<p> <p>
Yes. There are now several Go programs deployed in Yes. There are now several Go programs deployed in
production inside Google. For instance, the server behind production inside Google. A public example is the server behind
<a href="http://golang.org">http://golang.org</a> is a Go program; <a href="http://golang.org">http://golang.org</a>.
in fact it's just the <a href="/cmd/godoc"><code>godoc</code></a> It's just the <a href="/cmd/godoc"><code>godoc</code></a>
document server running in a production configuration. document server running in a production configuration on
<a href="http://code.google.com/appengine/">Google App Engine</a>.
</p> </p>
<h3 id="Do_Go_programs_link_with_Cpp_programs"> <h3 id="Do_Go_programs_link_with_Cpp_programs">
@ -362,7 +363,7 @@ because we feel it's sometimes worth trying a different approach.
Why build concurrency on the ideas of CSP?</h3> Why build concurrency on the ideas of CSP?</h3>
<p> <p>
Concurrency and multi-threaded programming have a reputation 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 designs such as pthreads and partly to overemphasis on low-level details
such as mutexes, condition variables, and memory barriers. such as mutexes, condition variables, and memory barriers.
Higher-level interfaces enable much simpler code, even if there are still Higher-level interfaces enable much simpler code, even if there are still
@ -433,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 also ways to embed types in other types to provide something
analogous&mdash;but not identical&mdash;to subclassing. analogous&mdash;but not identical&mdash;to subclassing.
Moreover, methods in Go are more general than in C++ or Java: 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>
<p> <p>
@ -446,7 +449,7 @@ How do I get dynamic dispatch of methods?</h3>
<p> <p>
The only way to have dynamically dispatched methods is through an 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> </p>
<h3 id="inheritance"> <h3 id="inheritance">
@ -541,7 +544,7 @@ interface <code>I</code> by attempting an assignment:
<pre> <pre>
type T struct{} type T struct{}
var _ I = T{} var _ I = T{} // Verify that T implements I.
</pre> </pre>
<p> <p>
@ -557,8 +560,8 @@ For example:
<pre> <pre>
type Fooer interface { type Fooer interface {
Foo() Foo()
ImplementsFooer() ImplementsFooer()
} }
</pre> </pre>
@ -590,7 +593,7 @@ itself with another value:
<pre> <pre>
type Equaler interface { type Equaler interface {
Equal(Equaler) bool Equal(Equaler) bool
} }
</pre> </pre>
@ -673,7 +676,7 @@ slice. This example converts a slice of <code>int</code> to a slice of
t := []int{1, 2, 3, 4} t := []int{1, 2, 3, 4}
s := make([]interface{}, len(t)) s := make([]interface{}, len(t))
for i, v := range t { for i, v := range t {
s[i] = v s[i] = v
} }
</pre> </pre>
@ -750,17 +753,22 @@ to write one but it will not be as convenient syntactically; this seems a reason
</p> </p>
<h3 id="map_keys"> <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> <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; 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. there are multiple considerations involving shallow vs. deep comparison, pointer vs.
value comparison, how to deal with recursive structures, and so on. value comparison, how to deal with recursive types, and so on.
We may revisit this issue&mdash;and implementing equality for structs and arrays 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 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. equality of structs and arrays should mean, it was simpler to leave it out for now.
</p> </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"> <h3 id="references">
Why are maps, slices, and channels references while arrays are values?</h3> Why are maps, slices, and channels references while arrays are values?</h3>
<p> <p>
@ -833,7 +841,7 @@ value makes a copy of the pointer, but not the data it points to.
</p> </p>
<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 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 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 makes a copy of the thing stored in the interface value. If the interface
@ -954,6 +962,8 @@ local to a function in that function's stack frame. However, if the
compiler cannot prove that the variable is not referenced after the compiler cannot prove that the variable is not referenced after the
function returns, then the compiler must allocate the variable on the function returns, then the compiler must allocate the variable on the
garbage-collected heap to avoid dangling pointer errors. 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>
<p> <p>
@ -993,10 +1003,8 @@ See the <a href="/doc/codewalk/sharemem/">Share Memory By Communicating</a> code
Why doesn't my multi-goroutine program use multiple CPUs?</h3> Why doesn't my multi-goroutine program use multiple CPUs?</h3>
<p> <p>
Under the gc compilers you must set <code>GOMAXPROCS</code> to allow the 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 run-time support to utilize more than one OS thread.
thread will be created for each goroutine, and <code>GOMAXPROCS</code> is
effectively equal to the number of running goroutines.
</p> </p>
<p> <p>
@ -1010,10 +1018,6 @@ documentation</a>.)
Why does using <code>GOMAXPROCS</code> &gt; 1 sometimes make my program Why does using <code>GOMAXPROCS</code> &gt; 1 sometimes make my program
slower?</h3> slower?</h3>
<p>
(This is specific to the gc compilers. See above.)
</p>
<p> <p>
It depends on the nature of your program. It depends on the nature of your program.
Programs that contain several goroutines that spend a lot of time Programs that contain several goroutines that spend a lot of time
@ -1067,7 +1071,7 @@ This is almost never the desired behavior.
</p> </p>
<h3 id="closures_and_goroutines"> <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> <p>
Some confusion may arise when using closures with concurrency. Some confusion may arise when using closures with concurrency.
@ -1076,29 +1080,30 @@ Consider the following program:
<pre> <pre>
func main() { func main() {
done := make(chan bool) done := make(chan bool)
values := []string{ "a", "b", "c" } values := []string{ "a", "b", "c" }
for _, v := range values { for _, v := range values {
go func() { go func() {
fmt.Println(v) fmt.Println(v)
done &lt;- true done &lt;- true
}() }()
} }
// wait for all goroutines to complete before exiting // wait for all goroutines to complete before exiting
for _ = range values { for _ = range values {
&lt;-done &lt;-done
} }
} }
</pre> </pre>
<p> <p>
One might mistakenly expect to see <code>a, b, c</code> as the output. 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 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 each iteration of the loop uses the same instance of the variable <code>v</code>, so
value of <code>v</code> at the time <code>fmt.Println</code> is executed, each closure shares that single variable. When the closure runs, it prints the
rather than the value of <code>v</code> when the goroutine was launched. 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>
<p> <p>
@ -1107,12 +1112,12 @@ could modify the inner loop to read:
</p> </p>
<pre> <pre>
for _, v := range values { for _, v := range values {
go func(<b>u</b> string) { go func(<b>u</b> string) {
fmt.Println(<b>u</b>) fmt.Println(<b>u</b>)
done &lt;- true done &lt;- true
}(<b>v</b>) }(<b>v</b>)
} }
</pre> </pre>
<p> <p>
@ -1133,9 +1138,9 @@ result:
<pre> <pre>
if expr { if expr {
n = trueVal n = trueVal
} else { } else {
n = falseVal n = falseVal
} }
</pre> </pre>
@ -1327,9 +1332,9 @@ import "unused"
var _ = unused.Item // TODO: Delete before committing! var _ = unused.Item // TODO: Delete before committing!
func main() { func main() {
debugData := debug.Profile() debugData := debug.Profile()
_ = debugData // Used only during debugging. _ = debugData // Used only during debugging.
.... ....
} }
</pre> </pre>
@ -1343,10 +1348,12 @@ 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 programs, yet on some benchmarks it does quite poorly, including several
in <a href="/test/bench/">test/bench</a>. The slowest depend on libraries 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 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 versions, unlike Go's, use <a href="http://gmplib.org/">GMP</a> (which is
written in optimized assembler). written in optimized assembler).
Benchmarks that depend on regular expressions (regex-dna, for instance) are 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 essentially comparing Go's native <a href="/pkg/regexp">regexp package</a> to
mature, highly optimized regular expression libraries like PCRE. mature, highly optimized regular expression libraries like PCRE.
</p> </p>
@ -1354,7 +1361,8 @@ mature, highly optimized regular expression libraries like PCRE.
<p> <p>
Benchmark games are won by extensive tuning and the Go versions of most Benchmark games are won by extensive tuning and the Go versions of most
of the benchmarks need attention. If you measure comparable C 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 languages are much closer in raw performance than this suite would
indicate. indicate.
</p> </p>
@ -1362,8 +1370,8 @@ indicate.
<p> <p>
Still, there is room for improvement. The compilers are good but could be Still, there is room for improvement. The compilers are good but could be
better, many libraries need major performance work, and the garbage collector better, many libraries need major performance work, and the garbage collector
isn't fast enough yet (even if it were, taking care not to generate unnecessary isn't fast enough yet. (Even if it were, taking care not to generate unnecessary
garbage can have a huge effect). garbage can have a huge effect.)
</p> </p>
<p> <p>
@ -1398,13 +1406,13 @@ prefix <code>*</code> for pointers is an exception that proves the rule). In C,
the declaration the declaration
</p> </p>
<pre> <pre>
int* a, b; int* a, b;
</pre> </pre>
<p> <p>
declares <code>a</code> to be a pointer but not <code>b</code>; in Go declares <code>a</code> to be a pointer but not <code>b</code>; in Go
</p> </p>
<pre> <pre>
var a, b *int var a, b *int
</pre> </pre>
<p> <p>
declares both to be pointers. This is clearer and more regular. declares both to be pointers. This is clearer and more regular.
@ -1412,11 +1420,11 @@ Also, the <code>:=</code> short declaration form argues that a full variable
declaration should present the same order as <code>:=</code> so declaration should present the same order as <code>:=</code> so
</p> </p>
<pre> <pre>
var a uint64 = 1 var a uint64 = 1
</pre> </pre>
has the same effect as has the same effect as
<pre> <pre>
a := uint64(1) a := uint64(1)
</pre> </pre>
<p> <p>
Parsing is also simplified by having a distinct grammar for types that Parsing is also simplified by having a distinct grammar for types that
@ -1495,8 +1503,7 @@ memory management. We feel it's critical to eliminate that
programmer overhead, and advances in garbage collection programmer overhead, and advances in garbage collection
technology in the last few years give us confidence that we can technology in the last few years give us confidence that we can
implement it with low enough overhead and no significant implement it with low enough overhead and no significant
latency. (The current implementation is a plain mark-and-sweep latency.
collector but a replacement is in the works.)
</p> </p>
<p> <p>
@ -1515,6 +1522,11 @@ Finally, concurrency aside, garbage collection makes interfaces
simpler because they don't need to specify how memory is managed across them. simpler because they don't need to specify how memory is managed across them.
</p> </p>
<p>
The current implementation is a parallel mark-and-sweep
collector but a future version might take a different approach.
</p>
<p> <p>
On the topic of performance, keep in mind that Go gives the programmer On the topic of performance, keep in mind that Go gives the programmer
considerable control over memory layout and allocation, much more than considerable control over memory layout and allocation, much more than