mirror of
https://github.com/golang/go
synced 2024-11-23 08:00:05 -07:00
3a7fe36d66
Fixes #7449. LGTM=bradfitz R=golang-codereviews, bradfitz CC=golang-codereviews https://golang.org/cl/71610044
1899 lines
68 KiB
HTML
1899 lines
68 KiB
HTML
<!--{
|
|
"Title": "Frequently Asked Questions (FAQ)",
|
|
"Path": "/doc/faq"
|
|
}-->
|
|
|
|
<h2 id="Origins">Origins</h2>
|
|
|
|
<h3 id="What_is_the_purpose_of_the_project">
|
|
What is the purpose of the project?</h3>
|
|
|
|
<p>
|
|
No major systems language has emerged in over a decade, but over that time
|
|
the computing landscape has changed tremendously. There are several trends:
|
|
</p>
|
|
|
|
<ul>
|
|
<li>
|
|
Computers are enormously quicker but software development is not faster.
|
|
<li>
|
|
Dependency management is a big part of software development today but the
|
|
“header files” of languages in the C tradition are antithetical to clean
|
|
dependency analysis—and fast compilation.
|
|
<li>
|
|
There is a growing rebellion against cumbersome type systems like those of
|
|
Java and C++, pushing people towards dynamically typed languages such as
|
|
Python and JavaScript.
|
|
<li>
|
|
Some fundamental concepts such as garbage collection and parallel computation
|
|
are not well supported by popular systems languages.
|
|
<li>
|
|
The emergence of multicore computers has generated worry and confusion.
|
|
</ul>
|
|
|
|
<p>
|
|
We believe it's worth trying again with a new language, a concurrent,
|
|
garbage-collected language with fast compilation. Regarding the points above:
|
|
</p>
|
|
|
|
<ul>
|
|
<li>
|
|
It is possible to compile a large Go program in a few seconds on a single computer.
|
|
<li>
|
|
Go provides a model for software construction that makes dependency
|
|
analysis easy and avoids much of the overhead of C-style include files and
|
|
libraries.
|
|
<li>
|
|
Go's type system has no hierarchy, so no time is spent defining the
|
|
relationships between types. Also, although Go has static types the language
|
|
attempts to make types feel lighter weight than in typical OO languages.
|
|
<li>
|
|
Go is fully garbage-collected and provides fundamental support for
|
|
concurrent execution and communication.
|
|
<li>
|
|
By its design, Go proposes an approach for the construction of system
|
|
software on multicore machines.
|
|
</ul>
|
|
|
|
<p>
|
|
A much more expansive answer to this question is available in the article,
|
|
<a href="http://talks.golang.org/2012/splash.article">Go at Google:
|
|
Language Design in the Service of Software Engineering</a>.
|
|
|
|
<h3 id="What_is_the_status_of_the_project">
|
|
What is the status of the project?</h3>
|
|
|
|
<p>
|
|
Go became a public open source project on November 10, 2009.
|
|
After a couple of years of very active design and development, stability was called for and
|
|
Go 1 was <a href="http://blog.golang.org/2012/03/go-version-1-is-released.html">released</a>
|
|
on March 28, 2012.
|
|
Go 1, which includes a <a href="/ref/spec">language specification</a>,
|
|
<a href="/pkg/">standard libraries</a>,
|
|
and <a href="/cmd/go/">custom tools</a>,
|
|
provides a stable foundation for creating reliable products, projects, and publications.
|
|
</p>
|
|
|
|
<p>
|
|
With that stability established, we are using Go to develop programs, products, and tools rather than
|
|
actively changing the language and libraries.
|
|
In fact, the purpose of Go 1 is to provide <a href="/doc/go1compat.html">long-term stability</a>.
|
|
Backwards-incompatible changes will not be made to any Go 1 point release.
|
|
We want to use what we have to learn how a future version of Go might look, rather than to play with
|
|
the language underfoot.
|
|
</p>
|
|
|
|
<p>
|
|
Of course, development will continue on Go itself, but the focus will be on performance, reliability,
|
|
portability and the addition of new functionality such as improved support for internationalization.
|
|
</p>
|
|
|
|
<p>
|
|
There may well be a Go 2 one day, but not for a few years and it will be influenced by what we learn using Go 1 as it is today.
|
|
</p>
|
|
|
|
<h3 id="What_is_the_origin_of_the_name">
|
|
What is the origin of the name?</h3>
|
|
|
|
<p>
|
|
“Ogle” would be a good name for a Go debugger.
|
|
</p>
|
|
|
|
<h3 id="Whats_the_origin_of_the_mascot">
|
|
What's the origin of the mascot?</h3>
|
|
|
|
<p>
|
|
The mascot and logo were designed by
|
|
<a href="http://reneefrench.blogspot.com">Renée French</a>, who also designed
|
|
<a href="http://plan9.bell-labs.com/plan9/glenda.html">Glenda</a>,
|
|
the Plan 9 bunny.
|
|
The gopher is derived from one she used for an <a href="http://wfmu.org/">WFMU</a>
|
|
T-shirt design some years ago.
|
|
The logo and mascot are covered by the
|
|
<a href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0</a>
|
|
license.
|
|
</p>
|
|
|
|
<h3 id="history">
|
|
What is the history of the project?</h3>
|
|
<p>
|
|
Robert Griesemer, Rob Pike and Ken Thompson started sketching the
|
|
goals for a new language on the white board on September 21, 2007.
|
|
Within a few days the goals had settled into a plan to do something
|
|
and a fair idea of what it would be. Design continued part-time in
|
|
parallel with unrelated work. By January 2008, Ken had started work
|
|
on a compiler with which to explore ideas; it generated C code as its
|
|
output. By mid-year the language had become a full-time project and
|
|
had settled enough to attempt a production compiler. In May 2008,
|
|
Ian Taylor independently started on a GCC front end for Go using the
|
|
draft specification. Russ Cox joined in late 2008 and helped move the language
|
|
and libraries from prototype to reality.
|
|
</p>
|
|
|
|
<p>
|
|
Go became a public open source project on November 10, 2009.
|
|
Many people from the community have contributed ideas, discussions, and code.
|
|
</p>
|
|
|
|
<h3 id="creating_a_new_language">
|
|
Why are you creating a new language?</h3>
|
|
<p>
|
|
Go was born out of frustration with existing languages and
|
|
environments for systems programming. Programming had become too
|
|
difficult and the choice of languages was partly to blame. One had to
|
|
choose either efficient compilation, efficient execution, or ease of
|
|
programming; all three were not available in the same mainstream
|
|
language. Programmers who could were choosing ease over
|
|
safety and efficiency by moving to dynamically typed languages such as
|
|
Python and JavaScript rather than C++ or, to a lesser extent, Java.
|
|
</p>
|
|
|
|
<p>
|
|
Go is an attempt to combine the ease of programming of an interpreted,
|
|
dynamically typed
|
|
language with the efficiency and safety of a statically typed, compiled language.
|
|
It also aims to be modern, with support for networked and multicore
|
|
computing. Finally, it is intended to be <i>fast</i>: it should take
|
|
at most a few seconds to build a large executable on a single computer.
|
|
To meet these goals required addressing a number of
|
|
linguistic issues: an expressive but lightweight type system;
|
|
concurrency and garbage collection; rigid dependency specification;
|
|
and so on. These cannot be addressed well by libraries or tools; a new
|
|
language was called for.
|
|
</p>
|
|
|
|
<p>
|
|
The article <a href="http://talks.golang.org/2012/splash.article">Go at Google</a>
|
|
discusses the background and motivation behind the design of the Go language,
|
|
as well as providing more detail about many of the answers presented in this FAQ.
|
|
</p>
|
|
|
|
<h3 id="ancestors">
|
|
What are Go's ancestors?</h3>
|
|
<p>
|
|
Go is mostly in the C family (basic syntax),
|
|
with significant input from the Pascal/Modula/Oberon
|
|
family (declarations, packages),
|
|
plus some ideas from languages
|
|
inspired by Tony Hoare's CSP,
|
|
such as Newsqueak and Limbo (concurrency).
|
|
However, it is a new language across the board.
|
|
In every respect the language was designed by thinking
|
|
about what programmers do and how to make programming, at least the
|
|
kind of programming we do, more effective, which means more fun.
|
|
</p>
|
|
|
|
<h3 id="principles">
|
|
What are the guiding principles in the design?</h3>
|
|
<p>
|
|
Programming today involves too much bookkeeping, repetition, and
|
|
clerical work. As Dick Gabriel says, “Old programs read
|
|
like quiet conversations between a well-spoken research worker and a
|
|
well-studied mechanical colleague, not as a debate with a compiler.
|
|
Who'd have guessed sophistication bought such noise?”
|
|
The sophistication is worthwhile—no one wants to go back to
|
|
the old languages—but can it be more quietly achieved?
|
|
</p>
|
|
<p>
|
|
Go attempts to reduce the amount of typing in both senses of the word.
|
|
Throughout its design, we have tried to reduce clutter and
|
|
complexity. There are no forward declarations and no header files;
|
|
everything is declared exactly once. Initialization is expressive,
|
|
automatic, and easy to use. Syntax is clean and light on keywords.
|
|
Stuttering (<code>foo.Foo* myFoo = new(foo.Foo)</code>) is reduced by
|
|
simple type derivation using the <code>:=</code>
|
|
declare-and-initialize construct. And perhaps most radically, there
|
|
is no type hierarchy: types just <i>are</i>, they don't have to
|
|
announce their relationships. These simplifications allow Go to be
|
|
expressive yet comprehensible without sacrificing, well, sophistication.
|
|
</p>
|
|
<p>
|
|
Another important principle is to keep the concepts orthogonal.
|
|
Methods can be implemented for any type; structures represent data while
|
|
interfaces represent abstraction; and so on. Orthogonality makes it
|
|
easier to understand what happens when things combine.
|
|
</p>
|
|
|
|
<h2 id="Usage">Usage</h2>
|
|
|
|
<h3 id="Is_Google_using_go_internally"> Is Google using Go internally?</h3>
|
|
|
|
<p>
|
|
Yes. There are now several Go programs deployed in
|
|
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="https://developers.google.com/appengine/">Google App Engine</a>.
|
|
</p>
|
|
|
|
<p>
|
|
Other examples include the <a href="https://code.google.com/p/vitess/">Vitess</a>
|
|
system for large-scale SQL installations and Google's download server, <code>dl.google.com</code>,
|
|
which delivers Chrome binaries and other large installables such as <code>apt-get</code>
|
|
packages.
|
|
</p>
|
|
|
|
<h3 id="Do_Go_programs_link_with_Cpp_programs">
|
|
Do Go programs link with C/C++ programs?</h3>
|
|
|
|
<p>
|
|
There are two Go compiler implementations, <code>gc</code>
|
|
(the <code>6g</code> program and friends) and <code>gccgo</code>.
|
|
<code>Gc</code> uses a different calling convention and linker and can
|
|
therefore only be linked with C programs using the same convention.
|
|
There is such a C compiler but no C++ compiler.
|
|
<code>Gccgo</code> is a GCC front-end that can, with care, be linked with
|
|
GCC-compiled C or C++ programs.
|
|
</p>
|
|
|
|
<p>
|
|
The <a href="/cmd/cgo/">cgo</a> program provides the mechanism for a
|
|
“foreign function interface” to allow safe calling of
|
|
C libraries from Go code. SWIG extends this capability to C++ libraries.
|
|
</p>
|
|
|
|
|
|
<h3 id="Does_Go_support_Google_protocol_buffers">
|
|
Does Go support Google's protocol buffers?</h3>
|
|
|
|
<p>
|
|
A separate open source project provides the necessary compiler plugin and library.
|
|
It is available at
|
|
<a href="http://code.google.com/p/goprotobuf/">http://code.google.com/p/goprotobuf/</a>
|
|
</p>
|
|
|
|
|
|
<h3 id="Can_I_translate_the_Go_home_page">
|
|
Can I translate the Go home page into another language?</h3>
|
|
|
|
<p>
|
|
Absolutely. We encourage developers to make Go Language sites in their own languages.
|
|
However, if you choose to add the Google logo or branding to your site
|
|
(it does not appear on <a href="http://golang.org/">golang.org</a>),
|
|
you will need to abide by the guidelines at
|
|
<a href="http://www.google.com/permissions/guidelines.html">http://www.google.com/permissions/guidelines.html</a>
|
|
</p>
|
|
|
|
<h2 id="Design">Design</h2>
|
|
|
|
<h3 id="unicode_identifiers">
|
|
What's up with Unicode identifiers?</h3>
|
|
|
|
<p>
|
|
It was important to us to extend the space of identifiers from the
|
|
confines of ASCII. Go's rule—identifier characters must be
|
|
letters or digits as defined by Unicode—is simple to understand
|
|
and to implement but has restrictions. Combining characters are
|
|
excluded by design, for instance.
|
|
Until there
|
|
is an agreed external definition of what an identifier might be,
|
|
plus a definition of canonicalization of identifiers that guarantees
|
|
no ambiguity, it seemed better to keep combining characters out of
|
|
the mix. Thus we have a simple rule that can be expanded later
|
|
without breaking programs, one that avoids bugs that would surely arise
|
|
from a rule that admits ambiguous identifiers.
|
|
</p>
|
|
|
|
<p>
|
|
On a related note, since an exported identifier must begin with an
|
|
upper-case letter, identifiers created from “letters”
|
|
in some languages can, by definition, not be exported. For now the
|
|
only solution is to use something like <code>X日本語</code>, which
|
|
is clearly unsatisfactory; we are considering other options. The
|
|
case-for-visibility rule is unlikely to change however; it's one
|
|
of our favorite features of Go.
|
|
</p>
|
|
|
|
<h3 id="Why_doesnt_Go_have_feature_X">Why does Go not have feature X?</h3>
|
|
|
|
<p>
|
|
Every language contains novel features and omits someone's favorite
|
|
feature. Go was designed with an eye on felicity of programming, speed of
|
|
compilation, orthogonality of concepts, and the need to support features
|
|
such as concurrency and garbage collection. Your favorite feature may be
|
|
missing because it doesn't fit, because it affects compilation speed or
|
|
clarity of design, or because it would make the fundamental system model
|
|
too difficult.
|
|
</p>
|
|
|
|
<p>
|
|
If it bothers you that Go is missing feature <var>X</var>,
|
|
please forgive us and investigate the features that Go does have. You might find that
|
|
they compensate in interesting ways for the lack of <var>X</var>.
|
|
</p>
|
|
|
|
<h3 id="generics">
|
|
Why does Go not have generic types?</h3>
|
|
<p>
|
|
Generics may well be added at some point. We don't feel an urgency for
|
|
them, although we understand some programmers do.
|
|
</p>
|
|
|
|
<p>
|
|
Generics are convenient but they come at a cost in
|
|
complexity in the type system and run-time. We haven't yet found a
|
|
design that gives value proportionate to the complexity, although we
|
|
continue to think about it. Meanwhile, Go's built-in maps and slices,
|
|
plus the ability to use the empty interface to construct containers
|
|
(with explicit unboxing) mean in many cases it is possible to write
|
|
code that does what generics would enable, if less smoothly.
|
|
</p>
|
|
|
|
<p>
|
|
This remains an open issue.
|
|
</p>
|
|
|
|
<h3 id="exceptions">
|
|
Why does Go not have exceptions?</h3>
|
|
<p>
|
|
We believe that coupling exceptions to a control
|
|
structure, as in the <code>try-catch-finally</code> idiom, results in
|
|
convoluted code. It also tends to encourage programmers to label
|
|
too many ordinary errors, such as failing to open a file, as
|
|
exceptional.
|
|
</p>
|
|
|
|
<p>
|
|
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="/doc/articles/error_handling.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
|
|
conditions. The recovery mechanism is executed only as part of a
|
|
function's state being torn down after an error, which is sufficient
|
|
to handle catastrophe but requires no extra control structures and,
|
|
when used well, can result in clean error-handling code.
|
|
</p>
|
|
|
|
<p>
|
|
See the <a href="/doc/articles/defer_panic_recover.html">Defer, Panic, and Recover</a> article for details.
|
|
</p>
|
|
|
|
<h3 id="assertions">
|
|
Why does Go not have assertions?</h3>
|
|
|
|
<p>
|
|
Go doesn't provide assertions. They are undeniably convenient, but our
|
|
experience has been that programmers use them as a crutch to avoid thinking
|
|
about proper error handling and reporting. Proper error handling means that
|
|
servers continue operation after non-fatal errors instead of crashing.
|
|
Proper error reporting means that errors are direct and to the point,
|
|
saving the programmer from interpreting a large crash trace. Precise
|
|
errors are particularly important when the programmer seeing the errors is
|
|
not familiar with the code.
|
|
</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.
|
|
</p>
|
|
|
|
<h3 id="csp">
|
|
Why build concurrency on the ideas of CSP?</h3>
|
|
<p>
|
|
Concurrency and multi-threaded programming have a reputation
|
|
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
|
|
mutexes and such under the covers.
|
|
</p>
|
|
|
|
<p>
|
|
One of the most successful models for providing high-level linguistic support
|
|
for concurrency comes from Hoare's Communicating Sequential Processes, or CSP.
|
|
Occam and Erlang are two well known languages that stem from CSP.
|
|
Go's concurrency primitives derive from a different part of the family tree
|
|
whose main contribution is the powerful notion of channels as first class objects.
|
|
Experience with several earlier languages has shown that the CSP model
|
|
fits well into a procedural language framework.
|
|
</p>
|
|
|
|
<h3 id="goroutines">
|
|
Why goroutines instead of threads?</h3>
|
|
<p>
|
|
Goroutines are part of making concurrency easy to use. The idea, which has
|
|
been around for a while, is to multiplex independently executing
|
|
functions—coroutines—onto a set of threads.
|
|
When a coroutine blocks, such as by calling a blocking system call,
|
|
the run-time automatically moves other coroutines on the same operating
|
|
system thread to a different, runnable thread so they won't be blocked.
|
|
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
|
|
in long-running system calls, they cost little more than the memory
|
|
for the stack, which is just a few kilobytes.
|
|
</p>
|
|
|
|
<p>
|
|
To make the stacks small, Go's run-time uses segmented stacks. A newly
|
|
minted goroutine is given a few kilobytes, which is almost always enough.
|
|
When it isn't, the run-time allocates (and frees) extension segments automatically.
|
|
The overhead averages about three cheap instructions per function call.
|
|
It is practical to create hundreds of thousands of goroutines in the same
|
|
address space. If goroutines were just threads, system resources would
|
|
run out at a much smaller number.
|
|
</p>
|
|
|
|
<h3 id="atomic_maps">
|
|
Why are map operations not defined to be atomic?</h3>
|
|
|
|
<p>
|
|
After long discussion it was decided that the typical use of maps did not require
|
|
safe access from multiple goroutines, and in those cases where it did, the map was
|
|
probably part of some larger data structure or computation that was already
|
|
synchronized. Therefore requiring that all map operations grab a mutex would slow
|
|
down most programs and add safety to few. This was not an easy decision,
|
|
however, since it means uncontrolled map access can crash the program.
|
|
</p>
|
|
|
|
<p>
|
|
The language does not preclude atomic map updates. When required, such
|
|
as when hosting an untrusted program, the implementation could interlock
|
|
map access.
|
|
</p>
|
|
|
|
<h3 id="language_changes">
|
|
Will you accept my language change?</h3>
|
|
|
|
<p>
|
|
People often suggest improvements to the language—the
|
|
<a href="http://groups.google.com/group/golang-nuts">mailing list</a>
|
|
contains a rich history of such discussions—but very few of these changes have
|
|
been accepted.
|
|
</p>
|
|
|
|
<p>
|
|
Although Go is an open source project, the language and libraries are protected
|
|
by a <a href="/doc/go1compat.html">compatibility promise</a> that prevents
|
|
changes that break existing programs.
|
|
If your proposal violates the Go 1 specification we cannot even entertain the
|
|
idea, regardless of its merit.
|
|
A future major release of Go may be incompatible with Go 1, but we're not ready
|
|
to start talking about what that might be.
|
|
</p>
|
|
|
|
<p>
|
|
Even if your proposal is compatible with the Go 1 spec, it might
|
|
not be in the spirit of Go's design goals.
|
|
The article <i><a href="http://talks.golang.org/2012/splash.article">Go
|
|
at Google: Language Design in the Service of Software Engineering</a></i>
|
|
explains Go's origins and the motivation behind its design.
|
|
</p>
|
|
|
|
<h2 id="types">Types</h2>
|
|
|
|
<h3 id="Is_Go_an_object-oriented_language">
|
|
Is Go an object-oriented language?</h3>
|
|
|
|
<p>
|
|
Yes and no. Although Go has types and methods and allows an
|
|
object-oriented style of programming, there is no type hierarchy.
|
|
The concept of “interface” in Go provides a different approach that
|
|
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—but not identical—to subclassing.
|
|
Moreover, methods in Go are more general than in C++ or Java:
|
|
they can be defined for any sort of data, even built-in types such
|
|
as plain, “unboxed” integers.
|
|
They are not restricted to structs (classes).
|
|
</p>
|
|
|
|
<p>
|
|
Also, the lack of type hierarchy makes “objects” in Go feel much more
|
|
lightweight than in languages such as C++ or Java.
|
|
</p>
|
|
|
|
<h3 id="How_do_I_get_dynamic_dispatch_of_methods">
|
|
How do I get dynamic dispatch of methods?</h3>
|
|
|
|
<p>
|
|
The only way to have dynamically dispatched methods is through an
|
|
interface. Methods on a struct or any other concrete type are always resolved statically.
|
|
</p>
|
|
|
|
<h3 id="inheritance">
|
|
Why is there no type inheritance?</h3>
|
|
<p>
|
|
Object-oriented programming, at least in the best-known languages,
|
|
involves too much discussion of the relationships between types,
|
|
relationships that often could be derived automatically. Go takes a
|
|
different approach.
|
|
</p>
|
|
|
|
<p>
|
|
Rather than requiring the programmer to declare ahead of time that two
|
|
types are related, in Go a type automatically satisfies any interface
|
|
that specifies a subset of its methods. Besides reducing the
|
|
bookkeeping, this approach has real advantages. Types can satisfy
|
|
many interfaces at once, without the complexities of traditional
|
|
multiple inheritance.
|
|
Interfaces can be very lightweight—an interface with
|
|
one or even zero methods can express a useful concept.
|
|
Interfaces can be added after the fact if a new idea comes along
|
|
or for testing—without annotating the original types.
|
|
Because there are no explicit relationships between types
|
|
and interfaces, there is no type hierarchy to manage or discuss.
|
|
</p>
|
|
|
|
<p>
|
|
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>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.
|
|
Go's interfaces have a profound influence on how programs are structured.
|
|
</p>
|
|
|
|
<p>
|
|
It takes some getting used to but this implicit style of type
|
|
dependency is one of the most productive things about Go.
|
|
</p>
|
|
|
|
<h3 id="methods_on_basics">
|
|
Why is <code>len</code> a function and not a method?</h3>
|
|
<p>
|
|
We debated this issue but decided
|
|
implementing <code>len</code> and friends as functions was fine in practice and
|
|
didn't complicate questions about the interface (in the Go type sense)
|
|
of basic types.
|
|
</p>
|
|
|
|
<h3 id="overloading">
|
|
Why does Go not support overloading of methods and operators?</h3>
|
|
<p>
|
|
Method dispatch is simplified if it doesn't need to do type matching as well.
|
|
Experience with other languages told us that having a variety of
|
|
methods with the same name but different signatures was occasionally useful
|
|
but that it could also be confusing and fragile in practice. Matching only by name
|
|
and requiring consistency in the types was a major simplifying decision
|
|
in Go's type system.
|
|
</p>
|
|
|
|
<p>
|
|
Regarding operator overloading, it seems more a convenience than an absolute
|
|
requirement. Again, things are simpler without it.
|
|
</p>
|
|
|
|
<h3 id="implements_interface">
|
|
Why doesn't Go have "implements" declarations?</h3>
|
|
|
|
<p>
|
|
A Go type satisfies an interface by implementing the methods of that interface,
|
|
nothing more. This property allows interfaces to be defined and used without
|
|
having to modify existing code. It enables a kind of structural typing that
|
|
promotes separation of concerns and improves code re-use, and makes it easier
|
|
to build on patterns that emerge as the code develops.
|
|
The semantics of interfaces is one of the main reasons for Go's nimble,
|
|
lightweight feel.
|
|
</p>
|
|
|
|
<p>
|
|
See the <a href="#inheritance">question on type inheritance</a> for more detail.
|
|
</p>
|
|
|
|
<h3 id="guarantee_satisfies_interface">
|
|
How can I guarantee my type satisfies an interface?</h3>
|
|
|
|
<p>
|
|
You can ask the compiler to check that the type <code>T</code> implements the
|
|
interface <code>I</code> by attempting an assignment:
|
|
</p>
|
|
|
|
<pre>
|
|
type T struct{}
|
|
var _ I = T{} // Verify that T implements I.
|
|
</pre>
|
|
|
|
<p>
|
|
If <code>T</code> doesn't implement <code>I</code>, the mistake will be caught
|
|
at compile time.
|
|
</p>
|
|
|
|
<p>
|
|
If you wish the users of an interface to explicitly declare that they implement
|
|
it, you can add a method with a descriptive name to the interface's method set.
|
|
For example:
|
|
</p>
|
|
|
|
<pre>
|
|
type Fooer interface {
|
|
Foo()
|
|
ImplementsFooer()
|
|
}
|
|
</pre>
|
|
|
|
<p>
|
|
A type must then implement the <code>ImplementsFooer</code> method to be a
|
|
<code>Fooer</code>, clearly documenting the fact and announcing it in
|
|
<a href="/cmd/godoc/">godoc</a>'s output.
|
|
</p>
|
|
|
|
<pre>
|
|
type Bar struct{}
|
|
func (b Bar) ImplementsFooer() {}
|
|
func (b Bar) Foo() {}
|
|
</pre>
|
|
|
|
<p>
|
|
Most code doesn't make use of such constraints, since they limit the utility of
|
|
the interface idea. Sometimes, though, they're necessary to resolve ambiguities
|
|
among similar interfaces.
|
|
</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() 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">
|
|
Can I convert a []T to an []interface{}?</h3>
|
|
|
|
<p>
|
|
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>:
|
|
</p>
|
|
|
|
<pre>
|
|
t := []int{1, 2, 3, 4}
|
|
s := make([]interface{}, len(t))
|
|
for i, v := range t {
|
|
s[i] = v
|
|
}
|
|
</pre>
|
|
|
|
<h3 id="nil_error">
|
|
Why is my nil error value not equal to nil?
|
|
</h3>
|
|
|
|
<p>
|
|
Under the covers, interfaces are implemented as two elements, a type and a value.
|
|
The value, called the interface's dynamic value,
|
|
is an arbitrary concrete value and the type is that of the value.
|
|
For the <code>int</code> value 3, an interface value contains,
|
|
schematically, (<code>int</code>, <code>3</code>).
|
|
</p>
|
|
|
|
<p>
|
|
An interface value is <code>nil</code> only if the inner value and type are both unset,
|
|
(<code>nil</code>, <code>nil</code>).
|
|
In particular, a <code>nil</code> interface will always hold a <code>nil</code> type.
|
|
If we store a pointer of type <code>*int</code> inside
|
|
an interface value, the inner type will be <code>*int</code> regardless of the value of the pointer:
|
|
(<code>*int</code>, <code>nil</code>).
|
|
Such an interface value will therefore be non-<code>nil</code>
|
|
<em>even when the pointer inside is</em> <code>nil</code>.
|
|
</p>
|
|
|
|
<p>
|
|
This situation can be confusing, and often arises when a <code>nil</code> value is
|
|
stored inside an interface value such as an <code>error</code> return:
|
|
</p>
|
|
|
|
<pre>
|
|
func returnsError() error {
|
|
var p *MyError = nil
|
|
if bad() {
|
|
p = ErrBad
|
|
}
|
|
return p // Will always return a non-nil error.
|
|
}
|
|
</pre>
|
|
|
|
<p>
|
|
If all goes well, the function returns a <code>nil</code> <code>p</code>,
|
|
so the return value is an <code>error</code> interface
|
|
value holding (<code>*MyError</code>, <code>nil</code>).
|
|
This means that if the caller compares the returned error to <code>nil</code>,
|
|
it will always look as if there was an error even if nothing bad happened.
|
|
To return a proper <code>nil</code> <code>error</code> to the caller,
|
|
the function must return an explicit <code>nil</code>:
|
|
</p>
|
|
|
|
|
|
<pre>
|
|
func returnsError() error {
|
|
if bad() {
|
|
return ErrBad
|
|
}
|
|
return nil
|
|
}
|
|
</pre>
|
|
|
|
<p>
|
|
It's a good idea for functions
|
|
that return errors always to use the <code>error</code> type in
|
|
their signature (as we did above) rather than a concrete type such
|
|
as <code>*MyError</code>, to help guarantee the error is
|
|
created correctly. As an example,
|
|
<a href="/pkg/os/#Open"><code>os.Open</code></a>
|
|
returns an <code>error</code> even though, if not <code>nil</code>,
|
|
it's always of concrete type
|
|
<a href="/pkg/os/#PathError"><code>*os.PathError</code></a>.
|
|
</p>
|
|
|
|
<p>
|
|
Similar situations to those described here can arise whenever interfaces are used.
|
|
Just keep in mind that if any concrete value
|
|
has been stored in the interface, the interface will not be <code>nil</code>.
|
|
For more information, see
|
|
<a href="/doc/articles/laws_of_reflection.html">The Laws of Reflection</a>.
|
|
</p>
|
|
|
|
|
|
<h3 id="unions">
|
|
Why are there no untagged unions, as in C?</h3>
|
|
|
|
<p>
|
|
Untagged unions would violate Go's memory safety
|
|
guarantees.
|
|
</p>
|
|
|
|
<h3 id="variant_types">
|
|
Why does Go not have variant types?</h3>
|
|
|
|
<p>
|
|
Variant types, also known as algebraic types, provide a way to specify
|
|
that a value might take one of a set of other types, but only those
|
|
types. A common example in systems programming would specify that an
|
|
error is, say, a network error, a security error or an application
|
|
error and allow the caller to discriminate the source of the problem
|
|
by examining the type of the error. Another example is a syntax tree
|
|
in which each node can be a different type: declaration, statement,
|
|
assignment and so on.
|
|
</p>
|
|
|
|
<p>
|
|
We considered adding variant types to Go, but after discussion
|
|
decided to leave them out because they overlap in confusing ways
|
|
with interfaces. What would happen if the elements of a variant type
|
|
were themselves interfaces?
|
|
</p>
|
|
|
|
<p>
|
|
Also, some of what variant types address is already covered by the
|
|
language. The error example is easy to express using an interface
|
|
value to hold the error and a type switch to discriminate cases. The
|
|
syntax tree example is also doable, although not as elegantly.
|
|
</p>
|
|
|
|
<h2 id="values">Values</h2>
|
|
|
|
<h3 id="conversions">
|
|
Why does Go not provide implicit numeric conversions?</h3>
|
|
<p>
|
|
The convenience of automatic conversion between numeric types in C is
|
|
outweighed by the confusion it causes. When is an expression unsigned?
|
|
How big is the value? Does it overflow? Is the result portable, independent
|
|
of the machine on which it executes?
|
|
It also complicates the compiler; “the usual arithmetic conversions”
|
|
are not easy to implement and inconsistent across architectures.
|
|
For reasons of portability, we decided to make things clear and straightforward
|
|
at the cost of some explicit conversions in the code.
|
|
The definition of constants in Go—arbitrary precision values free
|
|
of signedness and size annotations—ameliorates matters considerably,
|
|
though.
|
|
</p>
|
|
|
|
<p>
|
|
A related detail is that, unlike in C, <code>int</code> and <code>int64</code>
|
|
are distinct types even if <code>int</code> is a 64-bit type. The <code>int</code>
|
|
type is generic; if you care about how many bits an integer holds, Go
|
|
encourages you to be explicit.
|
|
</p>
|
|
|
|
<h3 id="builtin_maps">
|
|
Why are maps built in?</h3>
|
|
<p>
|
|
The same reason strings are: they are such a powerful and important data
|
|
structure that providing one excellent implementation with syntactic support
|
|
makes programming more pleasant. We believe that Go's implementation of maps
|
|
is strong enough that it will serve for the vast majority of uses.
|
|
If a specific application can benefit from a custom implementation, it's possible
|
|
to write one but it will not be as convenient syntactically; this seems a reasonable tradeoff.
|
|
</p>
|
|
|
|
<h3 id="map_keys">
|
|
Why don't maps allow slices as keys?</h3>
|
|
<p>
|
|
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 types, and so on.
|
|
We may revisit this issue—and implementing equality for slices
|
|
will not invalidate any existing programs—but without a clear idea of what
|
|
equality of slices should mean, it was simpler to leave it out for now.
|
|
</p>
|
|
|
|
<p>
|
|
In Go 1, unlike prior releases, equality is defined for structs and arrays, so such
|
|
types can be used as map keys. Slices still do not have a definition of equality, though.
|
|
</p>
|
|
|
|
<h3 id="references">
|
|
Why are maps, slices, and channels references while arrays are values?</h3>
|
|
<p>
|
|
There's a lot of history on that topic. Early on, maps and channels
|
|
were syntactically pointers and it was impossible to declare or use a
|
|
non-pointer instance. Also, we struggled with how arrays should work.
|
|
Eventually we decided that the strict separation of pointers and
|
|
values made the language harder to use. Changing these
|
|
types to act as references to the associated, shared data structures resolved
|
|
these issues. This change added some regrettable complexity to the
|
|
language but had a large effect on usability: Go became a more
|
|
productive, comfortable language when it was introduced.
|
|
</p>
|
|
|
|
<h2 id="Writing_Code">Writing Code</h2>
|
|
|
|
<h3 id="How_are_libraries_documented">
|
|
How are libraries documented?</h3>
|
|
|
|
<p>
|
|
There is a program, <code>godoc</code>, written in Go, that extracts
|
|
package documentation from the source code. It can be used on the
|
|
command line or on the web. An instance is running at
|
|
<a href="http://golang.org/pkg/">http://golang.org/pkg/</a>.
|
|
In fact, <code>godoc</code> implements the full site at
|
|
<a href="http://golang.org/">http://golang.org/</a>.
|
|
</p>
|
|
|
|
<h3 id="Is_there_a_Go_programming_style_guide">
|
|
Is there a Go programming style guide?</h3>
|
|
|
|
<p>
|
|
Eventually, there may be a small number of rules to guide things
|
|
like naming, layout, and file organization.
|
|
The document <a href="effective_go.html">Effective Go</a>
|
|
contains some style advice.
|
|
More directly, the program <code>gofmt</code> is a pretty-printer
|
|
whose purpose is to enforce layout rules; it replaces the usual
|
|
compendium of do's and don'ts that allows interpretation.
|
|
All the Go code in the repository has been run through <code>gofmt</code>.
|
|
</p>
|
|
|
|
<p>
|
|
The document titled
|
|
<a href="http://golang.org/s/comments">Go Code Review Comments</a>
|
|
is a collection of very short essays about details of Go idiom that are often
|
|
missed by programmers.
|
|
It is a handy reference for people doing code reviews for Go projects.
|
|
</p>
|
|
|
|
<h3 id="How_do_I_submit_patches_to_the_Go_libraries">
|
|
How do I submit patches to the Go libraries?</h3>
|
|
|
|
<p>
|
|
The library sources are in <code>go/src/pkg</code>.
|
|
If you want to make a significant change, please discuss on the mailing list before embarking.
|
|
</p>
|
|
|
|
<p>
|
|
See the document
|
|
<a href="contribute.html">Contributing to the Go project</a>
|
|
for more information about how to proceed.
|
|
</p>
|
|
|
|
<h3 id="Why_does_the_project_use_Mercurial_and_not_git">
|
|
Why does the project use Mercurial and not git?</h3>
|
|
|
|
<p>
|
|
The Go project, hosted by Google Code at
|
|
<a href="http://code.google.com/p/go">code.google.com/p/go</a>,
|
|
uses Mercurial as its version control system.
|
|
When the project launched,
|
|
Google Code supported only Subversion and Mercurial.
|
|
Mercurial was a better choice because of its plugin mechanism
|
|
that allowed us to create the "codereview" plugin to connect
|
|
the project to the excellent code review tools at
|
|
<a href="http://codereview.appspot.com">codereview.appspot.com</a>.
|
|
</p>
|
|
|
|
<p>
|
|
Programmers who work
|
|
with the Go project's source rather than release downloads sometimes
|
|
ask for the project to switch to git.
|
|
That would be possible, but it would be a lot of work and
|
|
would also require reimplementing the codereview plugin.
|
|
Given that Mercurial works today, with code review support,
|
|
combined with the Go project's mostly linear, non-branching use of
|
|
version control, a switch to git doesn't seem worthwhile.
|
|
</p>
|
|
|
|
<h3 id="git_https">
|
|
Why does "go get" use HTTPS when cloning a repository?</h3>
|
|
|
|
<p>
|
|
Companies often permit outgoing traffic only on the standard TCP ports 80 (HTTP)
|
|
and 443 (HTTPS), blocking outgoing traffic on other ports, including TCP port 9418
|
|
(git) and TCP port 22 (SSH).
|
|
When using HTTPS instead of HTTP, <code>git</code> enforces certificate validation by
|
|
default, providing protection against man-in-the-middle, eavesdropping and tampering attacks.
|
|
The <code>go get</code> command therefore uses HTTPS for safety.
|
|
</p>
|
|
|
|
<p>
|
|
If you use <code>git</code> and prefer to push changes through SSH using your existing key
|
|
it's easy to work around this. For GitHub, try one of these solutions:
|
|
</p>
|
|
<ul>
|
|
<li>Manually clone the repository in the expected package directory:
|
|
<pre>
|
|
$ cd $GOPATH/src/github.com/username
|
|
$ git clone git@github.com:username/package.git
|
|
</pre>
|
|
</li>
|
|
<li>Force <code>git push</code> to use the <code>SSH</code> protocol by appending
|
|
these two lines to <code>~/.gitconfig</code>:
|
|
<pre>
|
|
[url "git@github.com:"]
|
|
pushInsteadOf = https://github.com/
|
|
</pre>
|
|
</li>
|
|
</ul>
|
|
|
|
<h3 id="get_version">
|
|
How should I manage package versions using "go get"?</h3>
|
|
|
|
<p>
|
|
"Go get" does not have any explicit concept of package versions.
|
|
Versioning is a source of significant complexity, especially in large code bases,
|
|
and we are unaware of any approach that works well at scale in a large enough
|
|
variety of situations to be appropriate to force on all Go users.
|
|
What "go get" and the larger Go toolchain do provide is isolation of
|
|
packages with different import paths.
|
|
For example, the standard library's <code>html/template</code> and <code>text/template</code>
|
|
coexist even though both are "package template".
|
|
This observation leads to some advice for package authors and package users.
|
|
</p>
|
|
|
|
<p>
|
|
Packages intended for public use should try to maintain backwards compatibility as they evolve.
|
|
The <a href="/doc/go1compat.html">Go 1 compatibility guidelines</a> are a good reference here:
|
|
don't remove exported names, encourage tagged composite literals, and so on.
|
|
If different functionality is required, add a new name instead of changing an old one.
|
|
If a complete break is required, create a new package with a new import path.</p>
|
|
|
|
<p>
|
|
If you're using an externally supplied package and worry that it might change in
|
|
unexpected ways, the simplest solution is to copy it to your local repository.
|
|
(This is the approach Google takes internally.)
|
|
Store the copy under a new import path that identifies it as a local copy.
|
|
For example, you might copy "original.com/pkg" to "you.com/external/original.com/pkg".
|
|
Keith Rarick's <a href="https://github.com/kr/goven">goven</a> is one tool to help automate this process.
|
|
</p>
|
|
|
|
<h2 id="Pointers">Pointers and Allocation</h2>
|
|
|
|
<h3 id="pass_by_value">
|
|
When are function parameters passed by value?</h3>
|
|
|
|
<p>
|
|
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, 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
|
|
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
|
|
value holds a struct, copying the interface value makes a copy of the
|
|
struct. If the interface value holds a pointer, copying the interface value
|
|
makes a copy of the pointer, but again not the data it points to.
|
|
</p>
|
|
|
|
<h3 id="pointer_to_interface">
|
|
When should I use a pointer to an interface?</h3>
|
|
|
|
<p>
|
|
Almost never. Pointers to interface values arise only in rare, tricky situations involving
|
|
disguising an interface value's type for delayed evaluation.
|
|
</p>
|
|
|
|
<p>
|
|
It is however a common mistake to pass a pointer to an interface value
|
|
to a function expecting an interface. The compiler will complain about this
|
|
error but the situation can still be confusing, because sometimes a
|
|
<a href="#different_method_sets">pointer
|
|
is necessary to satisfy an interface</a>.
|
|
The insight is that although a pointer to a concrete type can satisfy
|
|
an interface, with one exception <em>a pointer to an interface can never satisfy a interface</em>.
|
|
</p>
|
|
|
|
<p>
|
|
Consider the variable declaration,
|
|
</p>
|
|
|
|
<pre>
|
|
var w io.Writer
|
|
</pre>
|
|
|
|
<p>
|
|
The printing function <code>fmt.Fprintf</code> takes as its first argument
|
|
a value that satisfies <code>io.Writer</code>—something that implements
|
|
the canonical <code>Write</code> method. Thus we can write
|
|
</p>
|
|
|
|
<pre>
|
|
fmt.Fprintf(w, "hello, world\n")
|
|
</pre>
|
|
|
|
<p>
|
|
If however we pass the address of <code>w</code>, the program will not compile.
|
|
</p>
|
|
|
|
<pre>
|
|
fmt.Fprintf(&w, "hello, world\n") // Compile-time error.
|
|
</pre>
|
|
|
|
<p>
|
|
The one exception is that any value, even a pointer to an interface, can be assigned to
|
|
a variable of empty interface type (<code>interface{}</code>).
|
|
Even so, it's almost certainly a mistake if the value is a pointer to an interface;
|
|
the result can be confusing.
|
|
</p>
|
|
|
|
<h3 id="methods_on_values_or_pointers">
|
|
Should I define methods on values or pointers?</h3>
|
|
|
|
<pre>
|
|
func (s *MyStruct) pointerMethod() { } // method on pointer
|
|
func (s MyStruct) valueMethod() { } // method on value
|
|
</pre>
|
|
|
|
<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
|
|
examples) behaves exactly as if it were an argument to the method.
|
|
Whether to define the receiver as a value or as a pointer is the same
|
|
question, then, as whether a function argument should be a value or
|
|
a pointer.
|
|
There are several considerations.
|
|
</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 act as references, 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">
|
|
What's the difference between new and make?</h3>
|
|
|
|
<p>
|
|
In short: <code>new</code> allocates memory, <code>make</code> initializes
|
|
the slice, map, and channel types.
|
|
</p>
|
|
|
|
<p>
|
|
See the <a href="/doc/effective_go.html#allocation_new">relevant section
|
|
of Effective Go</a> for more details.
|
|
</p>
|
|
|
|
<h3 id="q_int_sizes">
|
|
What is the size of an <code>int</code> on a 64 bit machine?</h3>
|
|
|
|
<p>
|
|
The sizes of <code>int</code> and <code>uint</code> are implementation-specific
|
|
but the same as each other on a given platform.
|
|
For portability, code that relies on a particular
|
|
size of value should use an explicitly sized type, like <code>int64</code>.
|
|
Prior to Go 1.1, the 64-bit Go compilers (both gc and gccgo) used
|
|
a 32-bit representation for <code>int</code>. As of Go 1.1 they use
|
|
a 64-bit representation.
|
|
On the other hand, floating-point scalars and complex
|
|
numbers are always sized: <code>float32</code>, <code>complex64</code>,
|
|
etc., because programmers should be aware of precision when using
|
|
floating-point numbers.
|
|
The default size of a floating-point constant is <code>float64</code>.
|
|
</p>
|
|
|
|
<h3 id="stack_or_heap">
|
|
How do I know whether a variable is allocated on the heap or the stack?</h3>
|
|
|
|
<p>
|
|
From a correctness standpoint, you don't need to know.
|
|
Each variable in Go exists as long as there are references to it.
|
|
The storage location chosen by the implementation is irrelevant to the
|
|
semantics of the language.
|
|
</p>
|
|
|
|
<p>
|
|
The storage location does have an effect on writing efficient programs.
|
|
When possible, the Go compilers will allocate variables that are
|
|
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, 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>
|
|
|
|
<h3 id="Why_does_my_Go_process_use_so_much_virtual_memory">
|
|
Why does my Go process use so much virtual memory?</h3>
|
|
|
|
<p>
|
|
The Go memory allocator reserves a large region of virtual memory as an arena
|
|
for allocations. This virtual memory is local to the specific Go process; the
|
|
reservation does not deprive other processes of memory.
|
|
</p>
|
|
|
|
<p>
|
|
To find the amount of actual memory allocated to a Go process, use the Unix
|
|
<code>top</code> command and consult the <code>RES</code> (Linux) or
|
|
<code>RSIZE</code> (Mac OS X) columns.
|
|
<!-- TODO(adg): find out how this works on Windows -->
|
|
</p>
|
|
|
|
<h2 id="Concurrency">Concurrency</h2>
|
|
|
|
<h3 id="What_operations_are_atomic_What_about_mutexes">
|
|
What operations are atomic? What about mutexes?</h3>
|
|
|
|
<p>
|
|
We haven't fully defined it all yet, but some details about atomicity are
|
|
available in the <a href="/ref/mem">Go Memory Model specification</a>.
|
|
</p>
|
|
|
|
<p>
|
|
Regarding mutexes, the <a href="/pkg/sync">sync</a>
|
|
package implements them, but we hope Go programming style will
|
|
encourage people to try higher-level techniques. In particular, consider
|
|
structuring your program so that only one goroutine at a time is ever
|
|
responsible for a particular piece of data.
|
|
</p>
|
|
|
|
<p>
|
|
Do not communicate by sharing memory. Instead, share memory by communicating.
|
|
</p>
|
|
|
|
<p>
|
|
See the <a href="/doc/codewalk/sharemem/">Share Memory By Communicating</a> code walk and its <a href="http://blog.golang.org/2010/07/share-memory-by-communicating.html">associated article</a> for a detailed discussion of this concept.
|
|
</p>
|
|
|
|
<h3 id="Why_no_multi_CPU">
|
|
Why doesn't my multi-goroutine program use multiple CPUs?</h3>
|
|
|
|
<p>
|
|
You must set the <code>GOMAXPROCS</code> shell environment variable
|
|
or use the similarly-named <a href="/pkg/runtime/#GOMAXPROCS"><code>function</code></a>
|
|
of the runtime package to allow the
|
|
run-time support to utilize more than one OS thread.
|
|
</p>
|
|
|
|
<p>
|
|
Programs that perform parallel computation should benefit from an increase in
|
|
<code>GOMAXPROCS</code>.
|
|
However, be aware that
|
|
<a href="http://blog.golang.org/2013/01/concurrency-is-not-parallelism.html">concurrency
|
|
is not parallelism</a>.
|
|
</p>
|
|
|
|
<h3 id="Why_GOMAXPROCS">
|
|
Why does using <code>GOMAXPROCS</code> > 1 sometimes make my program
|
|
slower?</h3>
|
|
|
|
<p>
|
|
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>
|
|
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="/ref/spec#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>
|
|
Go's goroutine scheduler is not as good as it needs to be. In future, it
|
|
should recognize such cases and optimize its use of OS threads. For now,
|
|
<code>GOMAXPROCS</code> should be set on a per-application basis.
|
|
</p>
|
|
|
|
<p>
|
|
For more detail on this topic see the talk entitled,
|
|
<a href="http://blog.golang.org/2013/01/concurrency-is-not-parallelism.html">Concurrency
|
|
is not Parallelism</a>.
|
|
|
|
<h2 id="Functions_methods">Functions and Methods</h2>
|
|
|
|
<h3 id="different_method_sets">
|
|
Why do T and *T have different method sets?</h3>
|
|
|
|
<p>
|
|
From the <a href="/ref/spec#Types">Go Spec</a>:
|
|
</p>
|
|
|
|
<blockquote>
|
|
The method set of any other named type <code>T</code> consists of all methods
|
|
with receiver type <code>T</code>. The method set of the corresponding pointer
|
|
type <code>*T</code> is the set of all methods with receiver <code>*T</code> or
|
|
<code>T</code> (that is, it also contains the method set of <code>T</code>).
|
|
</blockquote>
|
|
|
|
<p>
|
|
If an interface value contains a pointer <code>*T</code>,
|
|
a method call can obtain a value by dereferencing the pointer,
|
|
but if an interface value contains a value <code>T</code>,
|
|
there is no useful way for a method call to obtain a pointer.
|
|
</p>
|
|
|
|
<p>
|
|
Even in cases where the compiler could take the address of a value
|
|
to pass to the method, if the method modifies the value the changes
|
|
will be lost in the caller.
|
|
As a common example, this code:
|
|
</p>
|
|
|
|
<pre>
|
|
var buf bytes.Buffer
|
|
io.Copy(buf, os.Stdin)
|
|
</pre>
|
|
|
|
<p>
|
|
would copy standard input into a <i>copy</i> of <code>buf</code>,
|
|
not into <code>buf</code> itself.
|
|
This is almost never the desired behavior.
|
|
</p>
|
|
|
|
<h3 id="closures_and_goroutines">
|
|
What happens with closures running as goroutines?</h3>
|
|
|
|
<p>
|
|
Some confusion may arise when using closures with concurrency.
|
|
Consider the following program:
|
|
</p>
|
|
|
|
<pre>
|
|
func main() {
|
|
done := make(chan bool)
|
|
|
|
values := []string{"a", "b", "c"}
|
|
for _, v := range values {
|
|
go func() {
|
|
fmt.Println(v)
|
|
done <- true
|
|
}()
|
|
}
|
|
|
|
// wait for all goroutines to complete before exiting
|
|
for _ = range values {
|
|
<-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 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.
|
|
To help detect this and other problems before they happen, run
|
|
<a href="http://golang.org/cmd/go/#hdr-Run_go_tool_vet_on_packages"><code>go vet</code></a>.
|
|
</p>
|
|
|
|
<p>
|
|
To bind the current value of <code>v</code> to each closure as it is launched, one
|
|
must modify the inner loop to create a new variable each iteration.
|
|
One way is to pass the variable as an argument to the closure:
|
|
</p>
|
|
|
|
<pre>
|
|
for _, v := range values {
|
|
go func(<b>u</b> string) {
|
|
fmt.Println(<b>u</b>)
|
|
done <- true
|
|
}(<b>v</b>)
|
|
}
|
|
</pre>
|
|
|
|
<p>
|
|
In this example, the value of <code>v</code> is passed as an argument to the
|
|
anonymous function. That value is then accessible inside the function as
|
|
the variable <code>u</code>.
|
|
</p>
|
|
|
|
<p>
|
|
Even easier is just to create a new variable, using a declaration style that may
|
|
seem odd but works fine in Go:
|
|
</p>
|
|
|
|
<pre>
|
|
for _, v := range values {
|
|
<b>v := v</b> // create a new 'v'.
|
|
go func() {
|
|
fmt.Println(<b>v</b>)
|
|
done <- true
|
|
}()
|
|
}
|
|
</pre>
|
|
|
|
<h2 id="Control_flow">Control flow</h2>
|
|
|
|
<h3 id="Does_Go_have_a_ternary_form">
|
|
Does Go have the <code>?:</code> operator?</h3>
|
|
|
|
<p>
|
|
There is no ternary form in Go. You may use the following to achieve the same
|
|
result:
|
|
</p>
|
|
|
|
<pre>
|
|
if expr {
|
|
n = trueVal
|
|
} else {
|
|
n = falseVal
|
|
}
|
|
</pre>
|
|
|
|
<h2 id="Packages_Testing">Packages and Testing</h2>
|
|
|
|
<h3 id="How_do_I_create_a_multifile_package">
|
|
How do I create a multifile package?</h3>
|
|
|
|
<p>
|
|
Put all the source files for the package in a directory by themselves.
|
|
Source files can refer to items from different files at will; there is
|
|
no need for forward declarations or a header file.
|
|
</p>
|
|
|
|
<p>
|
|
Other than being split into multiple files, the package will compile and test
|
|
just like a single-file package.
|
|
</p>
|
|
|
|
<h3 id="How_do_I_write_a_unit_test">
|
|
How do I write a unit test?</h3>
|
|
|
|
<p>
|
|
Create a new file ending in <code>_test.go</code> in the same directory
|
|
as your package sources. Inside that file, <code>import "testing"</code>
|
|
and write functions of the form
|
|
</p>
|
|
|
|
<pre>
|
|
func TestFoo(t *testing.T) {
|
|
...
|
|
}
|
|
</pre>
|
|
|
|
<p>
|
|
Run <code>go test</code> in that directory.
|
|
That script finds the <code>Test</code> functions,
|
|
builds a test binary, and runs it.
|
|
</p>
|
|
|
|
<p>See the <a href="/doc/code.html">How to Write Go Code</a> document,
|
|
the <a href="/pkg/testing/"><code>testing</code></a> package
|
|
and the <a href="/cmd/go/#hdr-Test_packages"><code>go test</code></a> subcommand for more details.
|
|
</p>
|
|
|
|
<h3 id="testing_framework">
|
|
Where is my favorite helper function for testing?</h3>
|
|
|
|
<p>
|
|
Go's standard <a href="/pkg/testing/"><code>testing</code></a> 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="/src/pkg/fmt/fmt_test.go">the formatting tests for the <code>fmt</code> package</a>.
|
|
</p>
|
|
|
|
|
|
<h2 id="Implementation">Implementation</h2>
|
|
|
|
<h3 id="What_compiler_technology_is_used_to_build_the_compilers">
|
|
What compiler technology is used to build the compilers?</h3>
|
|
|
|
<p>
|
|
<code>Gccgo</code> has a front end written in C++, with a recursive descent parser coupled to the
|
|
standard GCC back end. <code>Gc</code> is written in C using
|
|
<code>yacc</code>/<code>bison</code> for the parser.
|
|
Although it's a new program, it fits in the Plan 9 C compiler suite
|
|
(<a href="http://plan9.bell-labs.com/sys/doc/compiler.html">http://plan9.bell-labs.com/sys/doc/compiler.html</a>)
|
|
and uses a variant of the Plan 9 loader to generate ELF/Mach-O/PE binaries.
|
|
</p>
|
|
|
|
<p>
|
|
We considered writing <code>gc</code>, the original Go compiler, in Go itself but
|
|
elected not to do so because of the difficulties of bootstrapping and
|
|
especially of open source distribution—you'd need a Go compiler to
|
|
set up a Go environment. <code>Gccgo</code>, which came later, makes it possible to
|
|
consider writing a compiler in Go, which might well happen.
|
|
(Go would be a
|
|
fine language in which to implement a compiler; a native lexer and
|
|
parser are already available in the <a href="/pkg/go/"><code>go</code></a> package
|
|
and a type checker is in the works.)
|
|
</p>
|
|
|
|
<p>
|
|
We also considered using LLVM for <code>gc</code> but we felt it was too large and
|
|
slow to meet our performance goals.
|
|
</p>
|
|
|
|
<h3 id="How_is_the_run_time_support_implemented">
|
|
How is the run-time support implemented?</h3>
|
|
|
|
<p>
|
|
Again due to bootstrapping issues, the run-time code is mostly in C (with a
|
|
tiny bit of assembler) although Go is capable of implementing most of
|
|
it now. <code>Gccgo</code>'s run-time support uses <code>glibc</code>.
|
|
<code>Gc</code> uses a custom library to keep the footprint under
|
|
control; it is
|
|
compiled with a version of the Plan 9 C compiler that supports
|
|
segmented stacks for goroutines.
|
|
The <code>gccgo</code> compiler implements segmented
|
|
stacks on Linux only, supported by recent modifications to the gold 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 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>
|
|
|
|
<p>
|
|
A simple C "hello, world" program compiled and linked statically using gcc
|
|
on Linux is around 750 kB,
|
|
including an implementation of <code>printf</code>.
|
|
An equivalent Go program using <code>fmt.Printf</code>
|
|
is around 1.2 MB, but
|
|
that includes more powerful run-time support.
|
|
</p>
|
|
|
|
<h3 id="unused_variables_and_imports">
|
|
Can I stop these complaints about my unused variable/import?</h3>
|
|
|
|
<p>
|
|
The presence of an unused variable may indicate a bug, while
|
|
unused imports just slow down compilation.
|
|
Accumulate enough unused imports in your code tree and
|
|
things can get very slow.
|
|
For these reasons, Go allows neither.
|
|
</p>
|
|
|
|
<p>
|
|
When developing code, it's common to create these situations
|
|
temporarily and it can be annoying to have to edit them out before the
|
|
program will compile.
|
|
</p>
|
|
|
|
<p>
|
|
Some have asked for a compiler option to turn those checks off
|
|
or at least reduce them to warnings.
|
|
Such an option has not been added, though,
|
|
because compiler options should not affect the semantics of the
|
|
language and because the Go compiler does not report warnings, only
|
|
errors that prevent compilation.
|
|
</p>
|
|
|
|
<p>
|
|
There are two reasons for having no warnings. First, if it's worth
|
|
complaining about, it's worth fixing in the code. (And if it's not
|
|
worth fixing, it's not worth mentioning.) Second, having the compiler
|
|
generate warnings encourages the implementation to warn about weak
|
|
cases that can make compilation noisy, masking real errors that
|
|
<em>should</em> be fixed.
|
|
</p>
|
|
|
|
<p>
|
|
It's easy to address the situation, though. Use the blank identifier
|
|
to let unused things persist while you're developing.
|
|
</p>
|
|
|
|
<pre>
|
|
import "unused"
|
|
|
|
// This declaration marks the import as used by referencing an
|
|
// item from the package.
|
|
var _ = unused.Item // TODO: Delete before committing!
|
|
|
|
func main() {
|
|
debugData := debug.Profile()
|
|
_ = debugData // Used only during debugging.
|
|
....
|
|
}
|
|
</pre>
|
|
|
|
<h2 id="Performance">Performance</h2>
|
|
|
|
<h3 id="Why_does_Go_perform_badly_on_benchmark_x">
|
|
Why does Go perform badly on benchmark X?</h3>
|
|
|
|
<p>
|
|
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/shootout/">test/bench/shootout</a>. The slowest depend on libraries
|
|
for which versions of comparable performance are not available in Go.
|
|
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
|
|
(<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
|
|
(<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>
|
|
|
|
<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.)
|
|
</p>
|
|
|
|
<p>
|
|
In any case, Go can often be very competitive.
|
|
There has been significant improvement in the performance of many programs
|
|
as the language and tools have developed.
|
|
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>
|
|
|
|
<h3 id="different_syntax">
|
|
Why is the syntax so different from C?</h3>
|
|
<p>
|
|
Other than declaration syntax, the differences are not major and stem
|
|
from two desires. First, the syntax should feel light, without too
|
|
many mandatory keywords, repetition, or arcana. Second, the language
|
|
has been designed to be easy to analyze
|
|
and can be parsed without a symbol table. This makes it much easier
|
|
to build tools such as debuggers, dependency analyzers, automated
|
|
documentation extractors, IDE plug-ins, and so on. C and its
|
|
descendants are notoriously difficult in this regard.
|
|
</p>
|
|
|
|
<h3 id="declarations_backwards">
|
|
Why are declarations backwards?</h3>
|
|
<p>
|
|
They're only backwards if you're used to C. In C, the notion is that a
|
|
variable is declared like an expression denoting its type, which is a
|
|
nice idea, but the type and expression grammars don't mix very well and
|
|
the results can be confusing; consider function pointers. Go mostly
|
|
separates expression and type syntax and that simplifies things (using
|
|
prefix <code>*</code> for pointers is an exception that proves the rule). In C,
|
|
the declaration
|
|
</p>
|
|
<pre>
|
|
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
|
|
</pre>
|
|
<p>
|
|
declares both to be pointers. This is clearer and more regular.
|
|
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
|
|
</pre>
|
|
<p>
|
|
has the same effect as
|
|
</p>
|
|
<pre>
|
|
a := uint64(1)
|
|
</pre>
|
|
<p>
|
|
Parsing is also simplified by having a distinct grammar for types that
|
|
is not just the expression grammar; keywords such as <code>func</code>
|
|
and <code>chan</code> keep things clear.
|
|
</p>
|
|
|
|
<p>
|
|
See the article about
|
|
<a href="/doc/articles/gos_declaration_syntax.html">Go's Declaration Syntax</a>
|
|
for more details.
|
|
</p>
|
|
|
|
<h3 id="no_pointer_arithmetic">
|
|
Why is there no pointer arithmetic?</h3>
|
|
<p>
|
|
Safety. Without pointer arithmetic it's possible to create a
|
|
language that can never derive an illegal address that succeeds
|
|
incorrectly. Compiler and hardware technology have advanced to the
|
|
point where a loop using array indices can be as efficient as a loop
|
|
using pointer arithmetic. Also, the lack of pointer arithmetic can
|
|
simplify the implementation of the garbage collector.
|
|
</p>
|
|
|
|
<h3 id="inc_dec">
|
|
Why are <code>++</code> and <code>--</code> statements and not expressions? And why postfix, not prefix?</h3>
|
|
<p>
|
|
Without pointer arithmetic, the convenience value of pre- and postfix
|
|
increment operators drops. By removing them from the expression
|
|
hierarchy altogether, expression syntax is simplified and the messy
|
|
issues around order of evaluation of <code>++</code> and <code>--</code>
|
|
(consider <code>f(i++)</code> and <code>p[i] = q[++i]</code>)
|
|
are eliminated as well. The simplification is
|
|
significant. As for postfix vs. prefix, either would work fine but
|
|
the postfix version is more traditional; insistence on prefix arose
|
|
with the STL, a library for a language whose name contains, ironically, a
|
|
postfix increment.
|
|
</p>
|
|
|
|
<h3 id="semicolons">
|
|
Why are there braces but no semicolons? And why can't I put the opening
|
|
brace on the next line?</h3>
|
|
<p>
|
|
Go uses brace brackets for statement grouping, a syntax familiar to
|
|
programmers who have worked with any language in the C family.
|
|
Semicolons, however, are for parsers, not for people, and we wanted to
|
|
eliminate them as much as possible. To achieve this goal, Go borrows
|
|
a trick from BCPL: the semicolons that separate statements are in the
|
|
formal grammar but are injected automatically, without lookahead, by
|
|
the lexer at the end of any line that could be the end of a statement.
|
|
This works very well in practice but has the effect that it forces a
|
|
brace style. For instance, the opening brace of a function cannot
|
|
appear on a line by itself.
|
|
</p>
|
|
|
|
<p>
|
|
Some have argued that the lexer should do lookahead to permit the
|
|
brace to live on the next line. We disagree. Since Go code is meant
|
|
to be formatted automatically by
|
|
<a href="/cmd/gofmt/"><code>gofmt</code></a>,
|
|
<i>some</i> style must be chosen. That style may differ from what
|
|
you've used in C or Java, but Go is a new language and
|
|
<code>gofmt</code>'s style is as good as any other. More
|
|
important—much more important—the advantages of a single,
|
|
programmatically mandated format for all Go programs greatly outweigh
|
|
any perceived disadvantages of the particular style.
|
|
Note too that Go's style means that an interactive implementation of
|
|
Go can use the standard syntax one line at a time without special rules.
|
|
</p>
|
|
|
|
<h3 id="garbage_collection">
|
|
Why do garbage collection? Won't it be too expensive?</h3>
|
|
<p>
|
|
One of the biggest sources of bookkeeping in systems programs is
|
|
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.
|
|
</p>
|
|
|
|
<p>
|
|
Another point is that a large part of the difficulty of concurrent
|
|
and multi-threaded programming is memory management;
|
|
as objects get passed among threads it becomes cumbersome
|
|
to guarantee they become freed safely.
|
|
Automatic garbage collection makes concurrent code far easier to write.
|
|
Of course, implementing garbage collection in a concurrent environment is
|
|
itself a challenge, but meeting it once rather than in every
|
|
program helps everyone.
|
|
</p>
|
|
|
|
<p>
|
|
Finally, concurrency aside, garbage collection makes interfaces
|
|
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
|
|
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>
|