mirror of
https://github.com/golang/go
synced 2024-11-25 06:57:58 -07:00
FAQ: lots of small tweaks plus a couple of new discussions.
Expand the conversations about pointers, memory, and garbage collection. Describe the lack of co/contravariant typing. Fixes #1929. Fixes #1930. R=dsymonds, r, mirtchovski, edsrzf, hanwen, rsc CC=golang-dev https://golang.org/cl/4852041
This commit is contained in:
parent
be269b2f6d
commit
93c4a246a4
184
doc/go_faq.html
184
doc/go_faq.html
@ -8,6 +8,7 @@ What is the purpose of the project?</h3>
|
|||||||
<p>
|
<p>
|
||||||
No major systems language has emerged in over a decade, but over that time
|
No major systems language has emerged in over a decade, but over that time
|
||||||
the computing landscape has changed tremendously. There are several trends:
|
the computing landscape has changed tremendously. There are several trends:
|
||||||
|
</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
@ -26,11 +27,11 @@ are not well supported by popular systems languages.
|
|||||||
<li>
|
<li>
|
||||||
The emergence of multicore computers has generated worry and confusion.
|
The emergence of multicore computers has generated worry and confusion.
|
||||||
</ul>
|
</ul>
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
We believe it's worth trying again with a new language, a concurrent,
|
We believe it's worth trying again with a new language, a concurrent,
|
||||||
garbage-collected language with fast compilation. Regarding the points above:
|
garbage-collected language with fast compilation. Regarding the points above:
|
||||||
|
</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
@ -50,7 +51,6 @@ concurrent execution and communication.
|
|||||||
By its design, Go proposes an approach for the construction of system
|
By its design, Go proposes an approach for the construction of system
|
||||||
software on multicore machines.
|
software on multicore machines.
|
||||||
</ul>
|
</ul>
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3 id="What_is_the_origin_of_the_name">
|
<h3 id="What_is_the_origin_of_the_name">
|
||||||
What is the origin of the name?</h3>
|
What is the origin of the name?</h3>
|
||||||
@ -105,7 +105,8 @@ and libraries from prototype to reality.
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Many others have contributed ideas, discussions, and code.
|
Go became a public open source project on November 10, 2009.
|
||||||
|
Many people from the community have contributed ideas, discussions, and code.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h3 id="creating_a_new_language">
|
<h3 id="creating_a_new_language">
|
||||||
@ -314,7 +315,16 @@ exceptional.
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Go takes a different approach. Instead of exceptions, it has a couple
|
Go takes a different approach. For plain error handling, Go's multi-value
|
||||||
|
returns make it easy to report an error without overloading the return value.
|
||||||
|
<a href="http://blog.golang.org/2011/07/error-handling-and-go.html">A
|
||||||
|
canonical error type, coupled
|
||||||
|
with Go's other features</a>, makes error
|
||||||
|
handling pleasant but quite different from that in other languages.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Go also has a couple
|
||||||
of built-in functions to signal and recover from truly exceptional
|
of built-in functions to signal and recover from truly exceptional
|
||||||
conditions. The recovery mechanism is executed only as part of a
|
conditions. The recovery mechanism is executed only as part of a
|
||||||
function's state being torn down after an error, which is sufficient
|
function's state being torn down after an error, which is sufficient
|
||||||
@ -372,7 +382,7 @@ Why build concurrency on the ideas of CSP?</h3>
|
|||||||
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 the problem 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 even 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
|
||||||
mutexes and such under the covers.
|
mutexes and such under the covers.
|
||||||
</p>
|
</p>
|
||||||
@ -390,14 +400,14 @@ Why goroutines instead of threads?</h3>
|
|||||||
<p>
|
<p>
|
||||||
Goroutines are part of making concurrency easy to use. The idea, which has
|
Goroutines are part of making concurrency easy to use. The idea, which has
|
||||||
been around for a while, is to multiplex independently executing
|
been around for a while, is to multiplex independently executing
|
||||||
functions—coroutines, really—onto a set of threads.
|
functions—coroutines—onto a set of threads.
|
||||||
When a coroutine blocks, such as by calling a blocking system call,
|
When a coroutine blocks, such as by calling a blocking system call,
|
||||||
the run-time automatically moves other coroutines on the same operating
|
the run-time automatically moves other coroutines on the same operating
|
||||||
system thread to a different, runnable thread so they won't be blocked.
|
system thread to a different, runnable thread so they won't be blocked.
|
||||||
The programmer sees none of this, which is the point.
|
The programmer sees none of this, which is the point.
|
||||||
The result, which we call goroutines, can be very cheap: unless they spend a lot of time
|
The result, which we call goroutines, can be very cheap: unless they spend a lot of time
|
||||||
in long-running system calls, they cost little more than the memory
|
in long-running system calls, they cost little more than the memory
|
||||||
for the stack.
|
for the stack, which is just a few kilobytes.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -473,8 +483,8 @@ that specifies a subset of its methods. Besides reducing the
|
|||||||
bookkeeping, this approach has real advantages. Types can satisfy
|
bookkeeping, this approach has real advantages. Types can satisfy
|
||||||
many interfaces at once, without the complexities of traditional
|
many interfaces at once, without the complexities of traditional
|
||||||
multiple inheritance.
|
multiple inheritance.
|
||||||
Interfaces can be very lightweight—having one or even zero methods
|
Interfaces can be very lightweight—an interface with
|
||||||
in an interface can express useful concepts.
|
one or even zero methods can express a useful concept.
|
||||||
Interfaces can be added after the fact if a new idea comes along
|
Interfaces can be added after the fact if a new idea comes along
|
||||||
or for testing—without annotating the original types.
|
or for testing—without annotating the original types.
|
||||||
Because there are no explicit relationships between types
|
Because there are no explicit relationships between types
|
||||||
@ -494,7 +504,7 @@ stream ciphers. All these ideas stem from a single interface
|
|||||||
|
|
||||||
<p>
|
<p>
|
||||||
It takes some getting used to but this implicit style of type
|
It takes some getting used to but this implicit style of type
|
||||||
dependency is one of the most exciting things about Go.
|
dependency is one of the most productive things about Go.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h3 id="methods_on_basics">
|
<h3 id="methods_on_basics">
|
||||||
@ -588,6 +598,85 @@ the interface idea. Sometimes, though, they're necessary to resolve ambiguities
|
|||||||
among similar interfaces.
|
among similar interfaces.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<h3 id="t_and_equal_interface">
|
||||||
|
Why doesn't type T satisfy the Equal interface?</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Consider this simple interface to represent an object that can compare
|
||||||
|
itself with another value:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
type Equaler interface {
|
||||||
|
Equal(Equaler) bool
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
and this type, <code>T</code>:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
type T int
|
||||||
|
func (t T) Equal(u T) bool { return t == u } // does not satisfy Equaler
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Unlike the analogous situation in some polymorphic type systems,
|
||||||
|
<code>T</code> does not implement <code>Equaler</code>.
|
||||||
|
The argument type of <code>T.Equal</code> is <code>T</code>,
|
||||||
|
not literally the required type <code>Equaler</code>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
In Go, the type system does not promote the argument of
|
||||||
|
<code>Equal</code>; that is the programmer's responsibility, as
|
||||||
|
illustrated by the type <code>T2</code>, which does implement
|
||||||
|
<code>Equaler</code>:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
type T2 int
|
||||||
|
func (t T2) Equal(u Equaler) bool { return t == u.(T2) } // satisfies Equaler
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Even this isn't like other type systems, though, because in Go <em>any</em>
|
||||||
|
type that satisfies <code>Equaler</code> could be passed as the
|
||||||
|
argument to <code>T2.Equal</code>, and at run time we must
|
||||||
|
check that the argument is of type <code>T2</code>.
|
||||||
|
Some languages arrange to make that guarantee at compile time.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
A related example goes the other way:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
type Opener interface {
|
||||||
|
Open(name) Reader
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t T3) Open() *os.File
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
In Go, <code>T3</code> does not satisfy <code>Opener</code>,
|
||||||
|
although it might in another language.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
While it is true that Go's type system does less for the programmer
|
||||||
|
in such cases, the lack of subtyping makes the rules about
|
||||||
|
interface satisfaction very easy to state: are the function's names
|
||||||
|
and signatures exactly those of the interface?
|
||||||
|
Go's rule is also easy to implement efficiently.
|
||||||
|
We feel these benefits offset the lack of
|
||||||
|
automatic type promotion. Should Go one day adopt some form of generic
|
||||||
|
typing, we expect there would be a way to express the idea of these
|
||||||
|
examples and also have them be statically checked.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h3 id="convert_slice_of_interface">
|
<h3 id="convert_slice_of_interface">
|
||||||
Can I convert a []T to an []interface{}?</h3>
|
Can I convert a []T to an []interface{}?</h3>
|
||||||
|
|
||||||
@ -736,17 +825,62 @@ makes a copy of the pointer, but again not the data it points to.
|
|||||||
Should I define methods on values or pointers?</h3>
|
Should I define methods on values or pointers?</h3>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
func (s *MyStruct) someMethod() { } // method on pointer
|
func (s *MyStruct) pointerMethod() { } // method on pointer
|
||||||
func (s MyStruct) someMethod() { } // method on value
|
func (s MyStruct) valueMethod() { } // method on value
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
For programmers unaccustomed to pointers, the distinction between these
|
||||||
|
two examples can be confusing, but the situation is actually very simple.
|
||||||
When defining a method on a type, the receiver (<code>s</code> in the above
|
When defining a method on a type, the receiver (<code>s</code> in the above
|
||||||
example) behaves exactly is if it were an argument to the method. Define the
|
example) behaves exactly as if it were an argument to the method.
|
||||||
method on a pointer type if you need the method to modify the data the receiver
|
Whether to define the receiver as a value or as a pointer is the same
|
||||||
points to. Otherwise, it is often cleaner to define the method on a value type.
|
question, then, as whether a function argument should be a value or
|
||||||
|
a pointer.
|
||||||
|
There are several considerations.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
First, and most important, does the method need to modify the
|
||||||
|
receiver?
|
||||||
|
If it does, the receiver <em>must</em> be a pointer.
|
||||||
|
(Slices and maps are reference types, so their story is a little
|
||||||
|
more subtle, but for instance to change the length of a slice
|
||||||
|
in a method the receiver must still be a pointer.)
|
||||||
|
In the examples above, if <code>pointerMethod</code> modifies
|
||||||
|
the fields of <code>s</code>,
|
||||||
|
the caller will see those changes, but <code>valueMethod</code>
|
||||||
|
is called with a copy of the caller's argument (that's the definition
|
||||||
|
of passing a value), so changes it makes will be invisible to the caller.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
By the way, pointer receivers are identical to the situation in Java,
|
||||||
|
although in Java the pointers are hidden under the covers; it's Go's
|
||||||
|
value receivers that are unusual.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Second is the consideration of efficiency. If the receiver is large,
|
||||||
|
a big <code>struct</code> for instance, it will be much cheaper to
|
||||||
|
use a pointer receiver.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Next is consistency. If some of the methods of the type must have
|
||||||
|
pointer receivers, the rest should too, so the method set is
|
||||||
|
consistent regardless of how the type is used.
|
||||||
|
See the section on <a href="#different_method_sets">method sets</a>
|
||||||
|
for details.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
For types such as basic types, slices, and small <code>structs</code>,
|
||||||
|
a value receiver is very cheap so unless the semantics of the method
|
||||||
|
requires a pointer, a value receiver is efficient and clear.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
<h3 id="new_and_make">
|
<h3 id="new_and_make">
|
||||||
What's the difference between new and make?</h3>
|
What's the difference between new and make?</h3>
|
||||||
|
|
||||||
@ -1111,6 +1245,11 @@ 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>
|
||||||
|
In any case, Go can often be very competitive. See the blog post about
|
||||||
|
<a href="http://blog.golang.org/2011/06/profiling-go-programs.html">profiling
|
||||||
|
Go programs</a> for an informative example.
|
||||||
|
|
||||||
<h2 id="change_from_c">Changes from C</h2>
|
<h2 id="change_from_c">Changes from C</h2>
|
||||||
|
|
||||||
<h3 id="different_syntax">
|
<h3 id="different_syntax">
|
||||||
@ -1165,7 +1304,9 @@ and <code>chan</code> keep things clear.
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
See the <a href="http://blog.golang.org/2010/07/gos-declaration-syntax.html">Go's Declaration Syntax</a> article for more details.
|
See the article about
|
||||||
|
<a href="http://blog.golang.org/2010/07/gos-declaration-syntax.html">Go's Declaration Syntax</a>
|
||||||
|
for more details.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h3 id="no_pointer_arithmetic">
|
<h3 id="no_pointer_arithmetic">
|
||||||
@ -1252,3 +1393,14 @@ program helps everyone.
|
|||||||
Finally, concurrency aside, garbage collection makes interfaces
|
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>
|
||||||
|
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
|
||||||
|
the garbage collection overhead dramatically by using the language well;
|
||||||
|
see the article about
|
||||||
|
<a href="http://blog.golang.org/2011/06/profiling-go-programs.html">profiling
|
||||||
|
Go programs</a> for a worked example, including a demonstration of Go's
|
||||||
|
profiling tools.
|
||||||
|
</p>
|
||||||
|
Loading…
Reference in New Issue
Block a user