all: remove everything; moved to x/website
Change-Id: Ibf88119ca2a021dc1abf01b83abb9ac850127a91 Reviewed-on: https://go-review.googlesource.com/c/blog/+/324270 Trust: Russ Cox <rsc@golang.org> Run-TryBot: Russ Cox <rsc@golang.org> Reviewed-by: Russ Cox <rsc@golang.org>
3
AUTHORS
|
@ -1,3 +0,0 @@
|
|||
# This source code refers to The Go Authors for copyright purposes.
|
||||
# The master list of authors is in the main Go distribution,
|
||||
# visible at https://tip.golang.org/AUTHORS.
|
|
@ -1,26 +0,0 @@
|
|||
# Contributing to Go
|
||||
|
||||
Go is an open source project.
|
||||
|
||||
It is the work of hundreds of contributors. We appreciate your help!
|
||||
|
||||
## Filing issues
|
||||
|
||||
When [filing an issue](https://golang.org/issue/new), make sure to answer these five questions:
|
||||
|
||||
1. What version of Go are you using (`go version`)?
|
||||
2. What operating system and processor architecture are you using?
|
||||
3. What did you do?
|
||||
4. What did you expect to see?
|
||||
5. What did you see instead?
|
||||
|
||||
General questions should go to the [golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead of the issue tracker.
|
||||
The gophers there will answer or ask you to file an issue if you've tripped over a bug.
|
||||
|
||||
## Contributing code
|
||||
|
||||
Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html)
|
||||
before sending patches.
|
||||
|
||||
Unless otherwise noted, the Go source files are distributed under
|
||||
the BSD-style license found in the LICENSE file.
|
|
@ -1,3 +0,0 @@
|
|||
# This source code was written by the Go contributors.
|
||||
# The master list of contributors is in the main Go distribution,
|
||||
# visible at https://tip.golang.org/CONTRIBUTORS.
|
27
LICENSE
|
@ -1,27 +0,0 @@
|
|||
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
22
PATENTS
|
@ -1,22 +0,0 @@
|
|||
Additional IP Rights Grant (Patents)
|
||||
|
||||
"This implementation" means the copyrightable works distributed by
|
||||
Google as part of the Go project.
|
||||
|
||||
Google hereby grants to You a perpetual, worldwide, non-exclusive,
|
||||
no-charge, royalty-free, irrevocable (except as stated in this section)
|
||||
patent license to make, have made, use, offer to sell, sell, import,
|
||||
transfer and otherwise run, modify and propagate the contents of this
|
||||
implementation of Go, where such license applies only to those patent
|
||||
claims, both currently owned or controlled by Google and acquired in
|
||||
the future, licensable by Google that are necessarily infringed by this
|
||||
implementation of Go. This grant does not include claims that would be
|
||||
infringed only as a consequence of further modification of this
|
||||
implementation. If you or your agent or exclusive licensee institute or
|
||||
order or agree to the institution of patent litigation against any
|
||||
entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
||||
that this implementation of Go or any code incorporated within this
|
||||
implementation of Go constitutes direct or contributory patent
|
||||
infringement, or inducement of patent infringement, then any patent
|
||||
rights granted to you under this License for this implementation of Go
|
||||
shall terminate as of the date such litigation is filed.
|
70
README.md
|
@ -1,69 +1,5 @@
|
|||
# Go Blog
|
||||
# Go Blog (obsolete)
|
||||
|
||||
[![Go Reference](https://pkg.go.dev/badge/golang.org/x/blog.svg)](https://pkg.go.dev/golang.org/x/blog)
|
||||
This repository formerly held the Go Blog server code and content.
|
||||
|
||||
This repository holds the Go Blog server code and content.
|
||||
|
||||
## Download/Install
|
||||
|
||||
The easiest way to install is to run `go get -u golang.org/x/blog`. You can also
|
||||
manually git clone the repository to \$GOPATH/src/golang.org/x/blog.
|
||||
|
||||
## Running Locally
|
||||
|
||||
To run the blog server locally:
|
||||
|
||||
```
|
||||
go run . -reload
|
||||
```
|
||||
|
||||
and then visit [http://localhost:8080/](http://localhost:8080) in your browser.
|
||||
|
||||
## Contributing
|
||||
|
||||
Articles are written in the [x/tools/present][present] format.
|
||||
Articles on the blog should have broad interest to the Go community, and
|
||||
are mainly written by Go contributors. We encourage you to share your
|
||||
experiences using Go on your own website, and [to share them with the Go
|
||||
community][community]. [Hugo][hugo] is a static site server written in Go that
|
||||
makes it easy to write and share your stories.
|
||||
|
||||
[present]: https://godoc.org/golang.org/x/tools/present
|
||||
[community]: https://golang.org/help/
|
||||
[hugo]: https://gohugo.io/
|
||||
|
||||
## Report Issues / Send Patches
|
||||
|
||||
This repository uses Gerrit for code changes. To learn how to submit changes to
|
||||
this repository, see https://golang.org/doc/contribute.html.
|
||||
|
||||
The main issue tracker for the blog is located at
|
||||
https://github.com/golang/go/issues. Prefix your issue with "x/blog:" in the
|
||||
subject line, so it is easy to find.
|
||||
|
||||
## Deploying
|
||||
|
||||
The Google Cloud project triggers a fresh deploy of the blog on each submit
|
||||
but that deployment is published to a temporary URL.
|
||||
|
||||
To publish the blog to blog.golang.org, you need access to the
|
||||
Cloud Console for the golang-org project.
|
||||
Then:
|
||||
|
||||
1. Visit the
|
||||
[builds list](https://console.cloud.google.com/cloud-build/builds?project=golang-org&query=trigger_id%3D%22c99674d3-32c1-4aec-ade4-ae2d5a844369%22)
|
||||
and click on the build hash for the most recent build
|
||||
with trigger name “Redeploy-blog-on-blog-commit”.
|
||||
|
||||
Scrolling to the bottom of the build log, you will find a URL in a log message like
|
||||
|
||||
Deployed service [blog] to [https://TEMPORARYURL.appspot.com]
|
||||
|
||||
2. Copy that URL and load it in your browser. Check that it looks OK.
|
||||
|
||||
3. Assuming it does, visit the
|
||||
[AppEngine versions list](https://console.cloud.google.com/appengine/versions?project=golang-org&serviceId=blog).
|
||||
Click “Migrate Traffic” on the new entry to move 100% of the blog.golang.org
|
||||
traffic to the new version.
|
||||
|
||||
4. You're done.
|
||||
That material has since moved to [golang.org/x/website](https://golang.org/x/website).
|
||||
|
|
|
@ -1,137 +0,0 @@
|
|||
# Go Turns 10
|
||||
8 Nov 2019
|
||||
Summary: Happy 10th birthday, Go!
|
||||
|
||||
Russ Cox, for the Go team
|
||||
rsc@golang.org
|
||||
|
||||
##
|
||||
|
||||
Happy birthday, Go!
|
||||
|
||||
This weekend we celebrate the 10th anniversary of
|
||||
[the Go release](https://opensource.googleblog.com/2009/11/hey-ho-lets-go.html),
|
||||
marking the 10th birthday of Go as an open-source programming language
|
||||
and ecosystem for building modern networked software.
|
||||
|
||||
To mark the occasion,
|
||||
[Renee French](https://twitter.com/reneefrench),
|
||||
the creator of the
|
||||
[Go gopher](https://blog.golang.org/gopher),
|
||||
painted this delightful scene:
|
||||
|
||||
<a href="10years/gopher10th-large.jpg">
|
||||
.image 10years/gopher10th-small.jpg _ 850
|
||||
</a>
|
||||
|
||||
Celebrating 10 years of Go makes me think back to early November 2009,
|
||||
when we were getting ready to share Go with the world.
|
||||
We didn’t know what kind of reaction to expect,
|
||||
whether anyone would care about this little language.
|
||||
I hoped that even if no one ended up using Go,
|
||||
we would at least have drawn attention to some good ideas,
|
||||
especially Go’s approach to concurrency and interfaces,
|
||||
that could influence follow-on languages.
|
||||
|
||||
Once it became clear that people were excited about Go,
|
||||
I looked at the history of popular languages
|
||||
like C, C++, Perl, Python, and Ruby,
|
||||
examining how long each took to gain widespread adoption.
|
||||
For example, Perl seemed to me to have appeared fully-formed
|
||||
in the mid-to-late 1990s, with CGI scripts and the web,
|
||||
but it was first released in 1987.
|
||||
This pattern repeated for almost every language I looked at:
|
||||
it seems to take roughly a decade of quiet, steady improvement
|
||||
and dissemination before a new language really takes off.
|
||||
|
||||
I wondered: where would Go be after a decade?
|
||||
|
||||
Today, we can answer that question:
|
||||
Go is everywhere, used by at least [a million developers worldwide](https://research.swtch.com/gophercount).
|
||||
|
||||
Go’s original target was networked system infrastructure,
|
||||
what we now call cloud software.
|
||||
Every major cloud provider today uses core cloud infrastructure written in Go,
|
||||
such as Docker, Etcd, Istio, Kubernetes, Prometheus, and Terraform;
|
||||
the majority of the
|
||||
[Cloud Native Computing Foundation’s projects](https://www.cncf.io/projects/)
|
||||
are written in Go.
|
||||
Countless companies are using Go to move their own work to the cloud as well,
|
||||
from startups building from scratch
|
||||
to enterprises modernizing their software stack.
|
||||
Go has also found adoption well beyond its original cloud target,
|
||||
with uses ranging
|
||||
from
|
||||
controlling tiny embedded systems with
|
||||
[GoBot](https://gobot.io) and [TinyGo](https://tinygo.org/)
|
||||
to detecting cancer with
|
||||
[massive big data analysis and machine learning at GRAIL](https://medium.com/grail-eng/bigslice-a-cluster-computing-system-for-go-7e03acd2419b),
|
||||
and everything in between.
|
||||
|
||||
All this is to say that Go has succeeded beyond our wildest dreams.
|
||||
And Go’s success isn’t just about the language.
|
||||
It’s about the language, the ecosystem, and especially the community working together.
|
||||
|
||||
In 2009, the language was a good idea with a working sketch of an implementation.
|
||||
The `go` command did not exist:
|
||||
we ran commands like `6g` to compile and `6l` to link binaries,
|
||||
automated with makefiles.
|
||||
We typed semicolons at the ends of statements.
|
||||
The entire program stopped during garbage collection,
|
||||
which then struggled to make good use of two cores.
|
||||
Go ran only on Linux and Mac, on 32- and 64-bit x86 and 32-bit ARM.
|
||||
|
||||
Over the last decade, with the help of Go developers all over the world,
|
||||
we have evolved this idea and sketch into a productive language
|
||||
with fantastic tooling,
|
||||
a production-quality implementation,
|
||||
a
|
||||
[state-of-the-art garbage collector](https://blog.golang.org/ismmkeynote),
|
||||
and [ports to 12 operating systems and 10 architectures](https://golang.org/doc/install/source#introduction).
|
||||
|
||||
Any programming language needs the support of a thriving ecosystem.
|
||||
The open source release was the seed for that ecosystem,
|
||||
but since then, many people have contributed their time and talent
|
||||
to fill the Go ecosystem with great tutorials, books, courses, blog posts,
|
||||
podcasts, tools, integrations, and of course reusable Go packages importable with `go` `get`.
|
||||
Go could never have succeeded without the support of this ecosystem.
|
||||
|
||||
Of course, the ecosystem needs the support of a thriving community.
|
||||
In 2019 there are dozens of Go conferences all over the world,
|
||||
along with
|
||||
[over 150 Go meetup groups with over 90,000 members](https://www.meetup.com/pro/go).
|
||||
[GoBridge](https://golangbridge.org)
|
||||
and
|
||||
[Women Who Go](https://medium.com/@carolynvs/www-loves-gobridge-ccb26309f667)
|
||||
help bring new voices into the Go community,
|
||||
through mentoring, training, and conference scholarships.
|
||||
This year alone, they have taught
|
||||
hundreds of people from traditionally underrepresented groups
|
||||
at workshops where community members teach and mentor those new to Go.
|
||||
|
||||
There are
|
||||
[over a million Go developers](https://research.swtch.com/gophercount)
|
||||
worldwide,
|
||||
and companies all over the globe are looking to hire more.
|
||||
In fact, people often tell us that learning Go
|
||||
helped them get their first jobs in the tech industry.
|
||||
In the end, what we’re most proud of about Go
|
||||
is not a well-designed feature or a clever bit of code
|
||||
but the positive impact Go has had in so many people’s lives.
|
||||
We aimed to create a language that would help us be better developers,
|
||||
and we are thrilled that Go has helped so many others.
|
||||
|
||||
As
|
||||
[\#GoTurns10](https://twitter.com/search?q=%23GoTurns10),
|
||||
I hope everyone will take a moment to celebrate
|
||||
the Go community and all we have achieved.
|
||||
On behalf of the entire Go team at Google,
|
||||
thank you to everyone who has joined us over the past decade.
|
||||
Let’s make the next one even more incredible!
|
||||
|
||||
<div>
|
||||
<center>
|
||||
<a href="10years/gopher10th-pin-large.jpg">
|
||||
.image 10years/gopher10th-pin-small.jpg _ 150
|
||||
</center>
|
||||
</div>
|
Двоичные данные
_content/10years/gopher10th-large.jpg
До Ширина: | Высота: | Размер: 1.8 MiB |
Двоичные данные
_content/10years/gopher10th-pin-large.jpg
До Ширина: | Высота: | Размер: 851 KiB |
Двоичные данные
_content/10years/gopher10th-pin-small.jpg
До Ширина: | Высота: | Размер: 78 KiB |
Двоичные данные
_content/10years/gopher10th-small.jpg
До Ширина: | Высота: | Размер: 455 KiB |
|
@ -1,233 +0,0 @@
|
|||
# Eleven Years of Go
|
||||
12:01 10 Nov 2020
|
||||
Summary: Happy Birthday, Go!
|
||||
|
||||
Russ Cox, for the Go team
|
||||
|
||||
##
|
||||
|
||||
Today we celebrate the eleventh birthday of the Go open source release.
|
||||
The parties we had for
|
||||
[Go turning 10](https://blog.golang.org/10years)
|
||||
seem like a distant memory.
|
||||
It’s been a tough year, but
|
||||
we’ve kept Go development moving forward
|
||||
and accumulated quite a few highlights.
|
||||
|
||||
In November, we launched [go.dev and pkg.go.dev](https://blog.golang.org/go.dev)
|
||||
shortly after Go’s 10th birthday.
|
||||
|
||||
In February, the [Go 1.14 release](https://blog.golang.org/go1.14)
|
||||
delivered the first officially “production-ready” implementation of Go modules,
|
||||
along with many performance improvements,
|
||||
including
|
||||
[faster defers](https://golang.org/design/34481-opencoded-defers)
|
||||
and
|
||||
[non-cooperative goroutine preemption](https://golang.org/design/24543/conservative-inner-frame)
|
||||
to reduce scheduling
|
||||
and garbage collection latency.
|
||||
|
||||
In early March, we launched a
|
||||
[new API for protocol buffers](https://blog.golang.org/protobuf-apiv2),
|
||||
[google.golang.org/protobuf](https://pkg.go.dev/google.golang.org/protobuf),
|
||||
with much-improved support for protocol buffer reflection and custom messages.
|
||||
|
||||
<img src="11years/gophermask.jpg" height="450" width="300" align="right" style="border: 2px solid black; margin: 0 0 1em 1em;">
|
||||
|
||||
When the pandemic hit, we decided to pause any public announcements
|
||||
or launches in the spring,
|
||||
recognizing that everyone’s attention rightly belonged elsewhere.
|
||||
But we kept working, and one of our team members joined the
|
||||
Apple/Google collaboration on
|
||||
[privacy-preserving exposure notifications](https://www.google.com/covid19/exposurenotifications/)
|
||||
to support contact tracing efforts all over the world.
|
||||
In May, that group launched the
|
||||
[reference backend server](https://github.com/google/exposure-notifications-server),
|
||||
written in Go.
|
||||
|
||||
We continued to improve [gopls](https://www.youtube.com/watch?v=EFJfdWzBHwE),
|
||||
which enables advanced
|
||||
[Go-aware support](https://github.com/golang/tools/blob/master/gopls/doc/user.md)
|
||||
in many editors.
|
||||
In June, the
|
||||
[VSCode Go extension officially joined the Go project](https://blog.golang.org/vscode-go)
|
||||
and is now maintained by the same developers who work on gopls.
|
||||
|
||||
Also in June, thanks to your feedback, we open-sourced
|
||||
[the code behind pkg.go.dev](https://blog.golang.org/pkgsite)
|
||||
as part of the Go project as well.
|
||||
|
||||
Later in June, we
|
||||
[released the latest design draft for generics](https://blog.golang.org/generics-next-step),
|
||||
along with a prototype tool and [generics playground](https://go2goplay.golang.org/).
|
||||
|
||||
In July, we published and discussed three new design drafts for future changes:
|
||||
[new `//go:build` lines for file selection](https://golang.org/design/draft-gobuild),
|
||||
[file system interfaces](https://golang.org/design/draft-iofs),
|
||||
and
|
||||
[build-time file embedding](https://golang.org/design/draft-embed).
|
||||
(We’ll see all of those in 2021, as noted below.)
|
||||
|
||||
In August, the [Go 1.15 release](https://blog.golang.org/go1.15)
|
||||
delivered mainly optimizations and bug fixes rather than new features.
|
||||
The most significant was the start of a rewrite of the linker,
|
||||
making it run 20% faster and use 30% less memory
|
||||
on average for large builds.
|
||||
|
||||
Last month, we ran our [annual Go user survey](https://blog.golang.org/survey2020).
|
||||
We will post results on the blog once we’ve analyzed them.
|
||||
|
||||
The Go community has adapted to “virtual-first” along with everyone else,
|
||||
and we saw many virtual meetups and over a dozen virtual Go conferences this year.
|
||||
Last week, the Go team hosted
|
||||
[Go day at Google Open Source Live](https://opensourcelive.withgoogle.com/events/go)
|
||||
(videos at the link).
|
||||
|
||||
## Going Forward
|
||||
|
||||
We’re also incredibly excited about what’s in store for Go’s 12th year.
|
||||
Most immediately, this week Go team members will
|
||||
be presenting eight events at
|
||||
[GopherCon 2020](https://www.gophercon.com/).
|
||||
Mark your calendars!
|
||||
|
||||
- “Typing [Generic] Go”,
|
||||
a talk by Robert Griesemer,\
|
||||
[Nov 11, 10:00 AM (US Eastern)](https://www.gophercon.com/agenda/session/233094);
|
||||
[Q&A at 10:30 AM](https://www.gophercon.com/agenda/session/417935).
|
||||
- “What to Expect When You’re NOT Expecting”,
|
||||
a live taping of the Go time podcast with a panel of expert debuggers,
|
||||
including Hana Kim,\
|
||||
[Nov 11 12:00 PM](https://www.gophercon.com/agenda/session/2334490).
|
||||
- “Evolving the Go Memory Manager's RAM and CPU Efficiency”,
|
||||
a talk by Michael Knyszek,\
|
||||
[Nov 11 1:00 PM](https://www.gophercon.com/agenda/session/233086);
|
||||
[Q&A at 1:50 PM](https://www.gophercon.com/agenda/session/417940).
|
||||
- “Implementing Faster Defers”,
|
||||
a talk by Dan Scales,\
|
||||
[Nov 11 5:10 PM](https://www.gophercon.com/agenda/session/233397);
|
||||
[Q&A at 5:40 PM](https://www.gophercon.com/agenda/session/417941).
|
||||
- “Go Team - Ask Me Anything”,
|
||||
a live Q&A with Julie Qiu, Rebecca Stambler, Russ Cox, Sameer Ajmani, and Van Riper,\
|
||||
[Nov 12 3:00 PM](https://www.gophercon.com/agenda/session/420539).
|
||||
- “Pardon the Interruption: Loop Preemption in Go 1.14”,
|
||||
a talk by Austin Clements,\
|
||||
[Nov 12 4:45 PM](https://www.gophercon.com/agenda/session/233441);
|
||||
[Q&A at 5:15 PM](https://www.gophercon.com/agenda/session/417943).
|
||||
- “Working with Errors”,
|
||||
a talk by Jonathan Amsterdam,\
|
||||
[Nov 13 1:00 PM](https://www.gophercon.com/agenda/session/233432);
|
||||
[Q&A at 1:50 PM](https://www.gophercon.com/agenda/session/417945).
|
||||
- “Crossing the Chasm for Go: Two Million Users and Growing”,
|
||||
a talk by Carmen Andoh,\
|
||||
[Nov 13 5:55 PM](https://www.gophercon.com/agenda/session/233426).
|
||||
|
||||
## Go Releases
|
||||
|
||||
In February, the Go 1.16 release will include the new
|
||||
[file system interfaces](https://tip.golang.org/pkg/io/fs/)
|
||||
and
|
||||
[build-time file embedding](https://tip.golang.org/pkg/embed/).
|
||||
It will complete the linker rewrite, bringing additional performance improvements.
|
||||
And it will include support for the new Apple Silicon (`GOARCH=arm64`) Macs.
|
||||
|
||||
In August, the Go 1.17 release will no doubt bring more features and improvements,
|
||||
although it’s far enough out that the exact details remain up in the air.
|
||||
It will include a new register-based calling convention for x86-64
|
||||
(without breaking existing assembly!),
|
||||
which will make programs faster across the board.
|
||||
(Other architectures will follow in later releases.)
|
||||
One nice feature that will definitely be included is the
|
||||
[new `//go:build` lines](https://golang.org/design/draft-gobuild),
|
||||
which are far less error-prone than the
|
||||
[current `//` `+build` lines](https://golang.org/cmd/go/#hdr-Build_constraints).
|
||||
Another highly anticipated feature we hope will be ready for beta testing next year
|
||||
is
|
||||
[support for fuzzing in the `go test` command](https://golang.org/design/draft-fuzzing).
|
||||
|
||||
## Go Modules
|
||||
|
||||
Over the next year, we will continue to work on developing support for Go modules
|
||||
and integrating them well into the entire Go ecosystem.
|
||||
Go 1.16 will include our smoothest Go modules experience yet.
|
||||
One preliminary result from our recent survey is that 96% of users
|
||||
have now adopted Go modules (up from 90% a year ago).
|
||||
|
||||
We will also finally wind down support for GOPATH-based development:
|
||||
any programs using dependencies other than the standard library will need a `go.mod`.
|
||||
(If you haven’t switched to modules yet, see the
|
||||
[GOPATH wiki page](https://golang.org/wiki/GOPATH)
|
||||
for details about this final step in the journey from GOPATH to modules.)
|
||||
|
||||
From the start, the [goal for Go modules](https://research.swtch.com/vgo-intro)
|
||||
has been “to add the concept of package versions to the working vocabulary
|
||||
of both Go developers and our tools,”
|
||||
to enable deep support for modules and versions throughout the Go ecosystem.
|
||||
The [Go module mirror, checksum database, and index](https://blog.golang.org/modules2019)
|
||||
were made possible by this ecosystem-wide understanding of what a package version is.
|
||||
Over the next year, we will see rich module support added to more tools and systems.
|
||||
For example, we plan to investigate new tooling to help module authors publish new versions
|
||||
(`go release`)
|
||||
as well as to help module consumers update their code to migrate away from
|
||||
deprecated APIs (a new `go fix`).
|
||||
|
||||
As a larger example,
|
||||
[we created gopls](https://github.com/golang/tools/blob/master/gopls/README.md)
|
||||
to reduce many tools used by editors for Go support,
|
||||
none of which supported modules, down to a single one that did.
|
||||
Over the next year,
|
||||
we’ll be ready to make the VSCode Go extension use `gopls` by default,
|
||||
for an excellent module experience out of the box,
|
||||
and we’ll release gopls 1.0.
|
||||
Of course, one of the best things about gopls is that it is editor-neutral:
|
||||
any editor that understands the
|
||||
[language server protocol](https://langserver.org/)
|
||||
can use it.
|
||||
|
||||
Another important use of version information is tracking whether
|
||||
any package in a build has a known vulnerability.
|
||||
Over the next year, we plan to develop a database of known vulnerabilities
|
||||
as well as tools to check your programs against that database.
|
||||
|
||||
The Go package discovery site
|
||||
[pkg.go.dev](https://pkg.go.dev/)
|
||||
is another example of a version-aware system enabled by Go modules.
|
||||
We’ve been focused on getting the core functionality and user experience right,
|
||||
including a
|
||||
[redesign launching today](https://blog.golang.org/pkgsite-redesign).
|
||||
Over the next year,
|
||||
we will be unifying godoc.org into pkg.go.dev.
|
||||
We will also be expanding the version timeline for each package,
|
||||
showing important changes in each version,
|
||||
known vulnerabilities, and more,
|
||||
following the overall goal of surfacing what you need to make
|
||||
[informed decisions about adding dependencies](https://research.swtch.com/deps).
|
||||
|
||||
We’re excited to see this journey from GOPATH to Go modules
|
||||
nearing completion and all the excellent dependency-aware tools
|
||||
that Go modules are enabling.
|
||||
|
||||
## Generics
|
||||
|
||||
The next feature on everyone’s minds is of course generics.
|
||||
As we mentioned above, we published the
|
||||
[latest design draft for generics](https://blog.golang.org/generics-next-step)
|
||||
back in June.
|
||||
Since then, we’ve continued to refine rough edges and have turned our
|
||||
attention to the details of implementing a production-ready version.
|
||||
We will be working on that throughout 2021, with a goal of having
|
||||
something for people to try out by the end of the year,
|
||||
perhaps a part of the Go 1.18 betas.
|
||||
|
||||
## Thank You!
|
||||
|
||||
Go is far more than just us on the Go team at Google.
|
||||
We are indebted to the contributors who work with us with the Go releases and tools.
|
||||
Beyond that, Go only succeeds because of all of you who work in
|
||||
and contribute to Go’s thriving ecosystem.
|
||||
It has been a difficult year in the world outside Go.
|
||||
More than ever, we appreciate you taking the time
|
||||
to join us and help make Go such a success.
|
||||
Thank you.
|
||||
We hope you are all staying safe and wish you all the best.
|
||||
|
Двоичные данные
_content/11years/gophermask.jpg
До Ширина: | Высота: | Размер: 44 KiB |
|
@ -1,148 +0,0 @@
|
|||
# Go: one year ago today
|
||||
10 Nov 2010
|
||||
Tags: birthday
|
||||
Summary: Happy 1st birthday, Go!
|
||||
OldURL: /go-one-year-ago-today
|
||||
|
||||
Andrew Gerrand
|
||||
|
||||
##
|
||||
|
||||
On the 10th of November 2009 we launched the Go project:
|
||||
an open-source programming language with a focus on simplicity and efficiency.
|
||||
The intervening year has seen a great many developments both in the Go project
|
||||
itself and in its community.
|
||||
|
||||
We set out to build a language for systems programming - the kinds of programs
|
||||
one might typically write in C or C++ - and we were surprised by Go’s
|
||||
utility as a general purpose language.
|
||||
We had anticipated interest from C, C++, and Java programmers,
|
||||
but the flurry of interest from users of dynamically-typed languages like
|
||||
Python and JavaScript was unexpected.
|
||||
Go’s combination of native compilation,
|
||||
static typing, memory management, and lightweight syntax seemed to strike
|
||||
a chord with a broad cross-section of the programming community.
|
||||
|
||||
That cross-section grew to become a dedicated community of enthusiastic Go coders.
|
||||
Our [mailing list](http://groups.google.com/group/golang-nuts) has over 3,800 members,
|
||||
with around 1,500 posts each month.
|
||||
The project has over 130 [contributors](https://golang.org/CONTRIBUTORS)
|
||||
(people who have submitted code or documentation),
|
||||
and of the 2,800 commits since launch almost one third were contributed
|
||||
by programmers outside the core team.
|
||||
To get all that code into shape, nearly 14,000 emails were exchanged on
|
||||
our [development mailing list](http://groups.google.com/group/golang-dev).
|
||||
|
||||
Those numbers reflect a labor whose fruits are evident in the project’s code base.
|
||||
The compilers have improved substantially,
|
||||
with faster and more efficient code generation,
|
||||
more than one hundred reported bugs fixed,
|
||||
and support for a widening range of operating systems and architectures.
|
||||
The Windows port is approaching completion thanks to a dedicated group of
|
||||
contributors (one of whom became our first non-Google committer to the project).
|
||||
The ARM port has also made great progress,
|
||||
recently reaching the milestone of passing all tests.
|
||||
|
||||
The Go tool set has been expanded and improved.
|
||||
The Go documentation tool, [godoc](https://golang.org/cmd/godoc/),
|
||||
now supports the documentation of other source trees (you can browse and
|
||||
search your own code) and provides a ["code walk"](https://golang.org/doc/codewalk/)
|
||||
interface for presenting tutorial materials (among many more improvements).
|
||||
[Goinstall](https://golang.org/cmd/goinstall/) ,
|
||||
a new package management tool, allows users to install and update external
|
||||
packages with a single command.
|
||||
[Gofmt](https://golang.org/cmd/gofmt/),
|
||||
the Go pretty-printer, now makes syntactic simplifications where possible.
|
||||
[Goplay](https://golang.org/misc/goplay/),
|
||||
a web-based “compile-as-you-type” tool,
|
||||
is a convenient way to experiment with Go for those times when you don’t
|
||||
have access to the [Go Playground](https://golang.org/doc/play/).
|
||||
|
||||
The standard library has grown by over 42,000 lines of code and includes
|
||||
20 new [packages](https://golang.org/pkg/).
|
||||
Among the additions are the [jpeg](https://golang.org/pkg/image/jpeg/),
|
||||
[jsonrpc](https://golang.org/pkg/rpc/jsonrpc/),
|
||||
[mime](https://golang.org/pkg/mime/), [netchan](https://golang.org/pkg/netchan/),
|
||||
and [smtp](https://golang.org/pkg/smtp/) packages,
|
||||
as well as a slew of new [cryptography](https://golang.org/pkg/crypto/) packages.
|
||||
More generally, the standard library has been continuously refined and revised
|
||||
as our understanding of Go’s idioms deepens.
|
||||
|
||||
The debugging story has gotten better, too.
|
||||
Recent improvements to the DWARF output of the gc compilers make the GNU debugger,
|
||||
GDB, useful for Go binaries, and we’re actively working on making that
|
||||
debugging information more complete.
|
||||
(See the [ recent blog post](https://blog.golang.org/2010/11/debugging-go-code-status-report.html) for details.)
|
||||
|
||||
It’s now easier than ever to link against existing libraries written in
|
||||
languages other than Go.
|
||||
Go support is in the most recent [SWIG](http://www.swig.org/) release,
|
||||
version 2.0.1, making it easier to link against C and C++ code,
|
||||
and our [cgo](https://golang.org/cmd/cgo/) tool has seen many fixes and improvements.
|
||||
|
||||
[Gccgo](https://golang.org/doc/gccgo_install.html),
|
||||
the Go front end for the GNU C Compiler, has kept pace with the gc compiler
|
||||
as a parallel Go implementation.
|
||||
It now has a working garbage collector, and has been accepted into the GCC core.
|
||||
We’re now working toward making [gofrontend](http://code.google.com/p/gofrontend/)
|
||||
available as a BSD-licensed Go compiler front end,
|
||||
fully decoupled from GCC.
|
||||
|
||||
Outside the Go project itself Go is starting to be used to build real software.
|
||||
There are more than 200 Go programs and libraries listed on our [Project dashboard](http://godashboard.appspot.com/project),
|
||||
and hundreds more on [Google Code](http://code.google.com/hosting/search?q=label:Go)
|
||||
and [Github](https://github.com/search?q=language:Go).
|
||||
On our mailing list and IRC channel you can find coders from around the
|
||||
world who use Go for their programming projects.
|
||||
(See our [guest blog post](https://blog.golang.org/2010/10/real-go-projects-smarttwitter-and-webgo.html)
|
||||
from last month for a real-world example.) Internally at Google there are
|
||||
several teams that choose Go for building production software,
|
||||
and we have received reports from other companies that are developing sizable systems in Go.
|
||||
We have also been in touch with several educators who are using Go as a teaching language.
|
||||
|
||||
The language itself has grown and matured, too.
|
||||
In the past year we have received many feature requests.
|
||||
But Go is a small language, and we’ve worked hard to ensure that any new
|
||||
feature strikes the right compromise between simplicity and utility.
|
||||
Since the launch we have made a number of language changes,
|
||||
many of which were driven by feedback from the community.
|
||||
|
||||
- Semicolons are now optional in almost all instances. [spec](https://golang.org/doc/go_spec.html#Semicolons)
|
||||
- The new built-in functions `copy` and `append` make management of slices
|
||||
more efficient and straightforward.
|
||||
[spec](https://golang.org/doc/go_spec.html#Appending_and_copying_slices)
|
||||
- The upper and lower bounds may be omitted when making a sub-slice.
|
||||
This means that `s[:]` is shorthand for `s[0:len(s)]`.
|
||||
[spec](https://golang.org/doc/go_spec.html#Slices)
|
||||
- The new built-in function `recover` complements `panic` and `defer` as
|
||||
an error handling mechanism.
|
||||
[blog](https://blog.golang.org/2010/08/defer-panic-and-recover.html),
|
||||
[spec](https://golang.org/doc/go_spec.html#Handling_panics)
|
||||
- The new complex number types (`complex`,
|
||||
`complex64`, and `complex128`) simplify certain mathematical operations.
|
||||
[spec](https://golang.org/doc/go_spec.html#Complex_numbers),
|
||||
[spec](https://golang.org/doc/go_spec.html#Imaginary_literals)
|
||||
- The composite literal syntax permits the omission of redundant type information
|
||||
(when specifying two-dimensional arrays, for example).
|
||||
[release.2010-10-27](https://golang.org/doc/devel/release.html#2010-10-27),
|
||||
[spec](https://golang.org/doc/go_spec.html#Composite_literals)
|
||||
- A general syntax for variable function arguments (`...T`) and their propagation
|
||||
(`v...`) is now specified.
|
||||
[spec](https://golang.org/doc/go_spec.html#Function_Types),
|
||||
[ spec](https://golang.org/doc/go_spec.html#Passing_arguments_to_..._parameters),
|
||||
[release.2010-09-29](https://golang.org/doc/devel/release.html#2010-09-29)
|
||||
|
||||
Go is certainly ready for production use,
|
||||
but there is still room for improvement.
|
||||
Our focus for the immediate future is making Go programs faster and more
|
||||
efficient in the context of high performance systems.
|
||||
This means improving the garbage collector,
|
||||
optimizing generated code, and improving the core libraries.
|
||||
We’re also exploring some further additions to the type system to make
|
||||
generic programming easier.
|
||||
A lot has happened in a year; it’s been both thrilling and satisfying.
|
||||
We hope that this coming year will be even more fruitful than the last.
|
||||
|
||||
_If you’ve been meaning to get [back] into Go, now is a great time to do so! Check out the_
|
||||
[_Documentation_](https://golang.org/doc/docs.html) _and_ [_Getting Started_](https://golang.org/doc/install.html)
|
||||
_pages for more information, or just go nuts in the_ [_Go Playground_](https://golang.org/doc/play/).
|
|
@ -1,76 +0,0 @@
|
|||
# The Go Programming Language turns two
|
||||
10 Nov 2011
|
||||
Tags: appengine, community, gopher
|
||||
Summary: Happy 2nd birthday, Go!
|
||||
OldURL: /go-programming-language-turns-two
|
||||
|
||||
Andrew Gerrand
|
||||
|
||||
##
|
||||
|
||||
Two years ago a small team at Google went public with their fledgling project -
|
||||
the Go Programming Language.
|
||||
They presented a language spec, two compilers,
|
||||
a modest standard library, some novel tools,
|
||||
and plenty of accurate (albeit succinct) documentation.
|
||||
They watched with excitement as programmers around the world began to play with Go.
|
||||
The team continued to iterate and improve on what they had built,
|
||||
and were gradually joined by dozens - and then hundreds - of programmers
|
||||
from the open source community.
|
||||
The Go Authors went on to produce lots of libraries,
|
||||
new tools, and reams of [documentation](https://golang.org/doc/docs.html).
|
||||
They celebrated a successful year in the public eye with a [blog post](https://blog.golang.org/2010/11/go-one-year-ago-today.html)
|
||||
last November that concluded "Go is certainly ready for production use,
|
||||
but there is still room for improvement.
|
||||
Our focus for the immediate future is making Go programs faster and more
|
||||
efficient in the context of high performance systems."
|
||||
|
||||
Today is the second anniversary of Go's release,
|
||||
and Go is faster and more stable than ever.
|
||||
Careful tuning of Go's code generators, concurrency primitives,
|
||||
garbage collector, and core libraries have increased the performance of Go programs,
|
||||
and native support for [profiling](https://blog.golang.org/2011/06/profiling-go-programs.html)
|
||||
and [debugging](http://blog.golang.org/2011/10/debugging-go-programs-with-gnu-debugger.html)
|
||||
makes it easier to detect and remove performance issues in user code.
|
||||
Go is also now easier to learn with [A Tour of Go](http://tour.golang.org/),
|
||||
an interactive tutorial you can take from the comfort of your web browser.
|
||||
|
||||
This year we introduced the experimental [Go runtime](http://code.google.com/appengine/docs/go/)
|
||||
for Google's App Engine platform,
|
||||
and we have been steadily increasing the Go runtime's support for App Engine's APIs.
|
||||
Just this week we released [version 1.6.0](http://code.google.com/appengine/downloads.html)
|
||||
of the Go App Engine SDK,
|
||||
which includes support for [backends](http://code.google.com/appengine/docs/go/backends/overview.html)
|
||||
(long-running processes),
|
||||
finer control over datastore indexes, and various other improvements.
|
||||
Today, the Go runtime is near feature parity with - and is a viable alternative
|
||||
to - the Python and Java runtimes.
|
||||
In fact, we now serve [golang.org](https://golang.org/) by running a version
|
||||
of [godoc](https://golang.org/cmd/godoc/) on the App Engine service.
|
||||
|
||||
While 2010 was a year of discovery and experimentation,
|
||||
2011 was a year of fine tuning and planning for the future.
|
||||
This year we issued several "[release](https://golang.org/doc/devel/release.html)"
|
||||
versions of Go that were more reliable and better supported than weekly snapshots.
|
||||
We also introduced [gofix](https://golang.org/cmd/gofix/) to take the
|
||||
pain out of migrating to newer releases.
|
||||
Furthermore, last month we announced a [plan for Go version 1](https://blog.golang.org/2011/10/preview-of-go-version-1.html) -
|
||||
a release that will be supported for years to come.
|
||||
Work toward Go 1 is already underway and you can observe our progress by
|
||||
the latest weekly snapshot at [weekly.golang.org](http://weekly.golang.org/pkg/).
|
||||
|
||||
The plan is to launch Go 1 in early 2012.
|
||||
We hope to bring the Go App Engine runtime out of "experimental" status at the same time.
|
||||
|
||||
But that's not all. 2011 was an exciting year for the gopher, too.
|
||||
He has manifested himself as a plush toy (a highly prized gift at Google
|
||||
I/O and other Go talks) and in vinyl form (received by every attendee at
|
||||
OSCON and now available at the [Google Store](http://www.googlestore.com/Fun/Go+Gopher+Figurine.axd)).
|
||||
|
||||
.image 2years/2years-gophers.jpg
|
||||
|
||||
And, most surprisingly, at Halloween he made an appearance with his gopher girlfriend!
|
||||
|
||||
.image 2years/2years-costume.jpg
|
||||
|
||||
Photograph by [Chris Nokleberg](https://plus.google.com/106640494112897458359/posts).
|
Двоичные данные
_content/2years/2years-costume.jpg
До Ширина: | Высота: | Размер: 61 KiB |
Двоичные данные
_content/2years/2years-gophers.jpg
До Ширина: | Высота: | Размер: 38 KiB |
|
@ -1,78 +0,0 @@
|
|||
# Go turns three
|
||||
10 Nov 2012
|
||||
Tags: community, birthday
|
||||
Summary: Happy 3rd birthday, Go!
|
||||
OldURL: /go-turns-three
|
||||
|
||||
Russ Cox
|
||||
|
||||
##
|
||||
|
||||
The Go open source project is
|
||||
[three years old today](http://google-opensource.blogspot.com/2009/11/hey-ho-lets-go.html).
|
||||
|
||||
It's great to look at how far Go has come in those three years.
|
||||
When we launched, Go was an idea backed by two implementations that worked on Linux and OS X.
|
||||
The syntax, semantics, and libraries changed regularly as we reacted to feedback from users
|
||||
and experience with the language.
|
||||
|
||||
Since the open source launch,
|
||||
we've been joined by
|
||||
[hundreds of external contributors](https://golang.org/CONTRIBUTORS),
|
||||
who have extended and improved Go in myriad ways,
|
||||
including writing a Windows port from scratch.
|
||||
We added a package management system
|
||||
[goinstall](https://groups.google.com/d/msg/golang-nuts/8JFwR3ESjjI/cy7qZzN7Lw4J),
|
||||
which eventually became the
|
||||
[go command](https://golang.org/cmd/go/).
|
||||
We also added
|
||||
[support for Go on App Engine](https://blog.golang.org/2011/07/go-for-app-engine-is-now-generally.html).
|
||||
Over the past year we've also given [many talks](https://golang.org/doc/#talks), created an [interactive introductory tour](http://tour.golang.org/)
|
||||
and recently we added support for [executable examples in package documentation](https://golang.org/pkg/strings/#pkg-examples).
|
||||
|
||||
Perhaps the most important development in the past year
|
||||
was the launch of the first stable version,
|
||||
[Go 1](https://blog.golang.org/2012/03/go-version-1-is-released.html).
|
||||
People who write Go 1 programs can now be confident that their programs will
|
||||
continue to compile and run without change, in many environments,
|
||||
on a time scale of years.
|
||||
As part of the Go 1 launch we spent months cleaning up the
|
||||
[language and libraries](https://golang.org/doc/go1.html)
|
||||
to make it something that will age well.
|
||||
|
||||
We're working now toward the release of Go 1.1 in 2013. There will be some
|
||||
new functionality, but that release will focus primarily on making Go perform
|
||||
even better than it does today.
|
||||
|
||||
We're especially happy about the community that has grown around Go:
|
||||
the mailing list and IRC channels seem like they are overflowing with discussion,
|
||||
and a handful of Go books were published this year. The community is thriving.
|
||||
Use of Go in production environments has also taken off, especially since Go 1.
|
||||
|
||||
We use Go at Google in a variety of ways, many of them invisible to the outside world.
|
||||
A few visible ones include
|
||||
[serving Chrome and other downloads](https://groups.google.com/d/msg/golang-nuts/BNUNbKSypE0/E4qSfpx9qI8J),
|
||||
[scaling MySQL database at YouTube](http://code.google.com/p/vitess/),
|
||||
and of course running the
|
||||
[Go home page](https://golang.org/)
|
||||
on [App Engine](https://developers.google.com/appengine/docs/go/overview).
|
||||
Last year's
|
||||
[Thanksgiving Doodle](https://blog.golang.org/2011/12/from-zero-to-go-launching-on-google.html)
|
||||
and the recent
|
||||
[Jam with Chrome](http://www.jamwithchrome.com/technology)
|
||||
site are also served by Go programs.
|
||||
|
||||
Other companies and projects are using Go too, including
|
||||
[BBC Worldwide](http://www.quora.com/Go-programming-language/Is-Google-Go-ready-for-production-use/answer/Kunal-Anand),
|
||||
[Canonical](http://dave.cheney.net/wp-content/uploads/2012/08/august-go-meetup.pdf),
|
||||
[CloudFlare](http://blog.cloudflare.com/go-at-cloudflare),
|
||||
[Heroku](https://blog.golang.org/2011/04/go-at-heroku.html),
|
||||
[Novartis](https://plus.google.com/114945221884326152379/posts/d1SVaqkRyTL),
|
||||
[SoundCloud](http://backstage.soundcloud.com/2012/07/go-at-soundcloud/),
|
||||
[SmugMug](http://sorcery.smugmug.com/2012/04/06/deriving-json-types-in-go/),
|
||||
[StatHat](https://blog.golang.org/2011/12/building-stathat-with-go.html),
|
||||
[Tinkercad](https://tinkercad.com/about/jobs),
|
||||
and
|
||||
[many others](https://golang.org/wiki/GoUsers).
|
||||
|
||||
Here's to many more years of productive programming in Go.
|
|
@ -1,163 +0,0 @@
|
|||
# Four years of Go
|
||||
10 Nov 2013
|
||||
Tags: community, birthday
|
||||
Summary: Happy 4th birthday, Go!
|
||||
|
||||
Andrew Gerrand
|
||||
|
||||
##
|
||||
|
||||
Today marks the fourth anniversary of Go as an open source project.
|
||||
|
||||
.image 4years/4years-gopher.png
|
||||
|
||||
Rather than talk about our technical progress (there'll be much to talk about
|
||||
when we release Go 1.2 in a couple of weeks) we thought we would instead take
|
||||
this occasion to look at how the Go community has grown.
|
||||
|
||||
Let's start with a chart:
|
||||
|
||||
.image 4years/4years-graph.png
|
||||
|
||||
This chart shows the growth of Google searches for the term
|
||||
"[golang](http://www.google.com/trends/explore?hl=en-US#q=golang&date=10/2009+50m&cmpt=q)"
|
||||
over the past four years.
|
||||
Notice the knee in the curve around March 2012, when Go 1.0 was released.
|
||||
If these searches are a decent proxy for interest, then it's clear that
|
||||
interest in Go has grown remarkably since launch, and particularly so in the
|
||||
last 2 years.
|
||||
|
||||
But where is the interest coming from?
|
||||
|
||||
The open source community has embraced Go,
|
||||
with our community wiki listing [hundreds of Go projects](https://golang.org/wiki/Projects). Some popular ones:
|
||||
|
||||
- [Docker](http://docker.io) is a tool for packaging and running applications
|
||||
in lightweight containers.
|
||||
Docker makes it easy to isolate, package,
|
||||
and deploy applications, and is beloved by system administrators.
|
||||
Its creator Solomon Hykes cited Go's standard library,
|
||||
concurrency primitives, and ease of deployment as key factors,
|
||||
and said "To put it simply, if Docker had not been written in Go,
|
||||
it would not have been as successful."
|
||||
|
||||
- [Packer](http://packer.io) is a tool for automating the creation of
|
||||
machine images for deployment to virtual machines or cloud services.
|
||||
Its author, Mitchell Hashimoto, is now working on another Go project,
|
||||
[serf](http://www.serfdom.io/), a decentralized discovery service.
|
||||
Like Docker, these projects help with management of large-scale,
|
||||
cluster-based services.
|
||||
|
||||
- [Bitly](http://bit.ly)'s [NSQ](http://bitly.github.io/nsq/) is a realtime
|
||||
distributed messaging platform designed for fault-tolerance and high-availability,
|
||||
and is used in production at bitly and a bunch of other companies.
|
||||
|
||||
- [Canonical](http://canonical.com/)'s [JuJu](https://juju.ubuntu.com/)
|
||||
infrastructure automation system was rewritten in Go.
|
||||
Project lead Gustavo Niemeyer said "It's not a single aspect of Go that
|
||||
makes it a compelling choice,
|
||||
but rather the careful organization of well-crafted small pieces."
|
||||
|
||||
- The [raft](https://github.com/goraft/raft) package provides an implementation
|
||||
of the [Raft](https://ramcloud.stanford.edu/wiki/download/attachments/11370504/raft.pdf)
|
||||
distributed consensus protocol.
|
||||
It is the basis of Go projects like [etcd](https://github.com/coreos/etcd)
|
||||
and [SkyDNS](https://github.com/skynetservices/skydns).
|
||||
|
||||
- Other popular projects include [biogo](https://github.com/biogo/biogo),
|
||||
the [Gorilla Web Toolkit](http://www.gorillatoolkit.org/),
|
||||
[groupcache](https://github.com/golang/groupcache),
|
||||
Mozilla's [heka](https://github.com/mozilla-services/heka),
|
||||
the [kv](https://github.com/cznic/kv) and [ql](https://github.com/cznic/ql)
|
||||
lightweight storage systems,
|
||||
and the [Sky](http://skydb.io/) behavioral database.
|
||||
|
||||
But this is just the tip of the iceberg. The number of high-quality open
|
||||
source Go projects is phenomenal.
|
||||
Prolific Go hacker [Keith Rarick](http://xph.us/software/) put it well:
|
||||
"The state of the Go ecosystem after only four years is astounding.
|
||||
Compare Go in 2013 to Python in 1995 or Java in 1999. Or C++ in 1987!"
|
||||
|
||||
Businesses are enjoying Go, too. The [Go Users wiki page](https://golang.org/wiki/GoUsers)
|
||||
lists dozens of success stories (and if you use Go,
|
||||
please add yourself to it). Some examples:
|
||||
|
||||
- [CloudFlare](https://blog.cloudflare.com/go-at-cloudflare) built their
|
||||
distributed DNS service entirely with Go,
|
||||
and are in the process of migrating their gigabytes-per-minute logging infrastructure to the language.
|
||||
Programmer John Graham-Cumming said "We've found Go to be the perfect match for our needs:
|
||||
the combination of familiar syntax, a powerful type system,
|
||||
a strong network library and built-in concurrency means that more and more
|
||||
projects are being built here in Go."
|
||||
|
||||
- [SoundCloud](http://soundcloud.com) is an audio distribution service
|
||||
that has "dozens of [systems in Go](http://backstage.soundcloud.com/2012/07/go-at-soundcloud/),
|
||||
touching almost every part of the site, and in many cases powering features
|
||||
from top to bottom." Engineer Peter Bourgon said "Go demonstrates that the
|
||||
cruft that burdens other languages and ecosystems—stuff that developers
|
||||
have learned to deal with,
|
||||
often in anger—is simply not a necessary part of modern programming.
|
||||
With Go, I have a straightforward and non-adversarial relationship with my tools,
|
||||
from development to production."
|
||||
|
||||
- The [ngrok](https://ngrok.com/) service allows web developers to provide
|
||||
remote access to their development environments.
|
||||
Its author Alan Shreve said that "ngrok's success as a project is due in
|
||||
no small part to choosing Go as the implementation language," citing Go's HTTP libraries,
|
||||
efficiency, cross-platform compatibility,
|
||||
and ease of deployment as the major benefits.
|
||||
|
||||
- [Poptip](http://poptip.com) provides social analytics services,
|
||||
and product engineer Andy Bonventre said "What started as an experiment
|
||||
in writing a single service in Go turned into moving almost our entire infrastructure over to it.
|
||||
What I love about Go the most is not necessarily the features of the language,
|
||||
but the focus on tooling, testing, and other elements that make writing
|
||||
large applications much more manageable."
|
||||
|
||||
- Music collaboration startup [Splice](http://splice.com) chose to build
|
||||
their service with Go.
|
||||
Co-founder Matt Aimonetti said "We seriously studied and considered many
|
||||
programming languages,
|
||||
but Go's simplicity, efficiency, philosophy and community won us over."
|
||||
|
||||
- And, of course, engineering teams across Google are moving to Go.
|
||||
Engineer Matt Welsh recently [shared his experience](http://matt-welsh.blogspot.com.au/2013/08/rewriting-large-production-system-in-go.html)
|
||||
rewriting a large production service in Go.
|
||||
Other notable public examples include YouTube's [vitess project](https://github.com/youtube/vitess)
|
||||
and [dl.google.com](https://talks.golang.org/2013/oscon-dl.slide).
|
||||
We hope to share more stories like these soon.
|
||||
|
||||
In September 2012, [Apcera](http://apcera.com/) CEO Derek Collison [predicted](https://twitter.com/derekcollison/status/245522124666716160)
|
||||
that "Go will become the dominant language for systems work in [Infastructure-as-a-Service],
|
||||
Orchestration, and [Platform-as-a-Service] in 24 months." Looking at the list above,
|
||||
it's easy to believe that prediction.
|
||||
|
||||
So how can you get involved? Whether you're a seasoned Go programmer or just Go-curious,
|
||||
there are many ways to get started in the Go community:
|
||||
|
||||
- [Join your nearest Go User Group](https://blog.golang.org/getthee-to-go-meetup),
|
||||
where your local gophers meet to share their knowledge and experience.
|
||||
These groups are popping up all over the world.
|
||||
I have personally spoken at Go groups in Amsterdam,
|
||||
Berlin, Gothenburg, London, Moscow, Munich,
|
||||
New York City, Paris, San Francisco, Seoul,
|
||||
Stockholm, Sydney, Tokyo, and Warsaw;
|
||||
but there are [many more](https://golang.org/wiki/GoUserGroups)!
|
||||
|
||||
- Create or contribute to an open source Go project (or [to Go itself](https://golang.org/doc/contribute.html)).
|
||||
(And if you're building something, we'd love to hear from you on the [Go mailing list](http://groups.google.com/group/golang-nuts).)
|
||||
|
||||
- If you're in Europe in February 2014, come along to the [Go Devroom](https://code.google.com/p/go-wiki/wiki/Fosdem2014)
|
||||
at [FOSDEM 2014](https://fosdem.org/2014/).
|
||||
|
||||
- Attend [GopherCon](http://gophercon.com),
|
||||
the first major Go conference, in Denver in April 2014.
|
||||
The event is organized by the [Gopher Academy](http://www.gopheracademy.com),
|
||||
who also run a [Go job board](http://www.gopheracademy.com/jobs).
|
||||
|
||||
The Go team has been amazed by the growth of the Go community over the past
|
||||
four years. We are thrilled to see so many great things being built with Go,
|
||||
and deeply grateful to work with our wonderful and dedicated contributors.
|
||||
Thank you, everyone.
|
||||
|
||||
Here's to four more years!
|
Двоичные данные
_content/4years/4years-gopher.png
До Ширина: | Высота: | Размер: 8.6 KiB |
Двоичные данные
_content/4years/4years-graph.png
До Ширина: | Высота: | Размер: 14 KiB |
|
@ -1,104 +0,0 @@
|
|||
# Half a decade with Go
|
||||
10 Nov 2014
|
||||
Summary: Happy 5th birthday, Go!
|
||||
|
||||
Andrew Gerrand
|
||||
adg@golang.org
|
||||
|
||||
##
|
||||
|
||||
Five years ago we launched the Go project. It seems like only yesterday that we
|
||||
were preparing the initial public release: our
|
||||
[website](https://web.archive.org/web/20091112094121/http://golang.org/) was
|
||||
a lovely shade of yellow, we were calling Go a "systems language", and you had
|
||||
to terminate statements with a semicolon and write Makefiles to build your
|
||||
code. We had no idea how Go would be received. Would people share our vision
|
||||
and goals? Would people find Go useful?
|
||||
|
||||
At launch, there was a flurry of attention. Google had produced a new
|
||||
programming language, and everyone was eager to check it out. Some programmers
|
||||
were turned off by Go's conservative feature set—at first glance they saw
|
||||
"nothing to see here"—but a smaller group saw the beginnings of an ecosystem
|
||||
tailored to their needs as working software engineers. These few would form the
|
||||
kernel of the Go community.
|
||||
|
||||
.image 5years/gophers5th.jpg _ 850
|
||||
|
||||
[_Gopher_](/gopher) _illustration by_ [_Renee French_](http://reneefrench.blogspot.com.au/)
|
||||
|
||||
After the initial release, it took us a while to properly communicate the
|
||||
goals and design ethos behind Go. Rob Pike did so eloquently in his 2012 essay
|
||||
[_Go at Google: Language Design in the Service of Software Engineering_](https://talks.golang.org/2012/splash.article) and
|
||||
more personally in his blog post
|
||||
[_Less is exponentially more_](https://commandcenter.blogspot.com.au/2012/06/less-is-exponentially-more.html).
|
||||
Andrew Gerrand's
|
||||
[_Code that grows with grace_](http://vimeo.com/53221560)
|
||||
([slides](https://talks.golang.org/2012/chat.slide)) and
|
||||
[_Go for Gophers_](https://www.youtube.com/watch?v=dKGmK_Z1Zl0)
|
||||
([slides](https://talks.golang.org/2014/go4gophers.slide)) give a
|
||||
more in-depth, technical take on Go's design philosophy.
|
||||
|
||||
Over time, the few became many. The turning point for the project was the
|
||||
release of Go 1 in March 2012, which provided a stable language and standard
|
||||
library that developers could trust. By 2014, the project had hundreds of core
|
||||
contributors, the ecosystem had countless [libraries and tools](https://godoc.org/)
|
||||
maintained by thousands of developers, and the greater community had
|
||||
many passionate members (or, as we call them, "gophers"). Today, by our current
|
||||
metrics, the Go community is growing faster than we believed possible.
|
||||
|
||||
Where can those gophers be found? They are at the many Go events that are
|
||||
popping up around the world. This year we saw several dedicated Go conferences:
|
||||
the inaugural [GopherCon](https://blog.golang.org/gophercon) and
|
||||
[dotGo](http://www.dotgo.eu/) conferences in Denver and Paris, the
|
||||
[Go DevRoom at FOSDEM](https://blog.golang.org/fosdem14) and two more
|
||||
instances of the biannual [GoCon](https://github.com/GoCon/GoCon) conference
|
||||
in Tokyo. At each event, gophers from around the globe eagerly presented their
|
||||
Go projects. For the Go team, it is very satisfying to meet so many programmers
|
||||
that share our vision and excitement.
|
||||
|
||||
.image 5years/conferences.jpg
|
||||
|
||||
_More than 1,200 gophers attended GopherCon in Denver and dotGo in Paris._
|
||||
|
||||
There are also dozens of community-run
|
||||
[Go User Groups](https://golang.org/wiki/GoUserGroups) spread across cities
|
||||
worldwide. If you haven't visited your local group, consider going along. And
|
||||
if there isn't a group in your area, maybe you should
|
||||
[start one](https://blog.golang.org/getthee-to-go-meetup)?
|
||||
|
||||
Today, Go has found a home in the cloud. Go arrived as the industry underwent a
|
||||
tectonic shift toward cloud computing, and we were thrilled to see it quickly
|
||||
become an important part of that movement. Its simplicity, efficiency, built-in
|
||||
concurrency primitives, and modern standard library make it a great fit for
|
||||
cloud software development (after all, that's what it was designed for).
|
||||
Significant open source cloud projects like
|
||||
[Docker](https://www.docker.com/) and
|
||||
[Kubernetes](https://github.com/GoogleCloudPlatform/kubernetes) have been
|
||||
written in Go, and infrastructure companies like Google, CloudFlare, Canonical,
|
||||
Digital Ocean, GitHub, Heroku, and Microsoft are now using Go to do some heavy
|
||||
lifting.
|
||||
|
||||
So, what does the future hold? We think that 2015 will be Go's biggest year yet.
|
||||
|
||||
Go 1.4—in addition to its [new features and fixes](https://golang.org/doc/go1.4)—lays
|
||||
the groundwork for a new low-latency garbage collector and support for running
|
||||
Go on mobile devices. It is due to be released on December 1st 2014.
|
||||
We expect the new GC to be available in Go 1.5, due June 1st 2015, which will
|
||||
make Go appealing for a broader range of applications.
|
||||
We can't wait to see where people take it.
|
||||
|
||||
And there will be more great events, with [GothamGo](http://gothamgo.com/) in
|
||||
New York (15 Nov), another Go DevRoom at FOSDEM in Brussels (Jan 31 and Feb 1;
|
||||
[get involved!](https://groups.google.com/d/msg/golang-nuts/1xgBazQzs1I/hwrZ5ni8cTEJ)),
|
||||
[GopherCon India](http://www.gophercon.in/) in Bengaluru (19-21 Feb),
|
||||
the original [GopherCon](http://gophercon.com/) back at Denver in July, and
|
||||
[dotGo](http://www.dotgo.eu/) on again at Paris in November.
|
||||
|
||||
The Go team would like to extend its thanks to all the gophers out there.
|
||||
Here's to the next five years.
|
||||
|
||||
_To celebrate 5 years of Go, over the coming month the_
|
||||
[_Gopher Academy_](http://blog.gopheracademy.com/)
|
||||
_will publish a series of articles by prominent Go users. Be sure to check out_
|
||||
[_their blog_](http://blog.gopheracademy.com/)
|
||||
_for more Go action._
|
Двоичные данные
_content/5years/conferences.jpg
До Ширина: | Высота: | Размер: 98 KiB |
Двоичные данные
_content/5years/gophers5th.jpg
До Ширина: | Высота: | Размер: 215 KiB |
|
@ -1,51 +0,0 @@
|
|||
# Six years of Go
|
||||
10 Nov 2015
|
||||
Summary: Happy 6th birthday, Go!
|
||||
|
||||
Andrew Gerrand
|
||||
adg@golang.org
|
||||
|
||||
##
|
||||
|
||||
Six years ago today the Go language was released as an open source project.
|
||||
Since then, more than 780 contributors have made over 30,000 commits to the
|
||||
project's 22 repositories. The ecosystem continues to grow, with GitHub
|
||||
reporting more than 90,000 Go repositories. And, offline, we see new Go events
|
||||
and user groups pop up [around](https://blog.golang.org/gophercon2015)
|
||||
[the](https://blog.golang.org/gouk15)
|
||||
[world](https://blog.golang.org/gopherchina) with regularity.
|
||||
|
||||
.image 6years/6years-gopher.png
|
||||
|
||||
In August we [released Go 1.5](https://blog.golang.org/go1.5), the most
|
||||
significant release since Go 1. It features a completely
|
||||
[redesigned garbage collector](https://golang.org/doc/go1.5#gc) that makes
|
||||
the language more suitable for latency-sensitive applications; it marks the
|
||||
transition from a C-based compiler tool chain to one
|
||||
[written entirely in Go](https://golang.org/doc/go1.5#c); and it includes
|
||||
ports to [new architectures](https://golang.org/doc/go1.5#ports), with better
|
||||
support for ARM processors (the chips that power most smartphones).
|
||||
These improvements make Go better suited to a broader range of tasks, a trend
|
||||
that we hope will continue over the coming years.
|
||||
|
||||
Improvements to tools continue to boost developer productivity.
|
||||
We introduced the [execution tracer](https://golang.org/cmd/trace/) and the
|
||||
"[go doc](https://golang.org/cmd/go/#hdr-Show_documentation_for_package_or_symbol)"
|
||||
command, as well as more enhancements to our various
|
||||
[static analysis tools](https://talks.golang.org/2014/static-analysis.slide).
|
||||
We are also working on an
|
||||
[official Go plugin for Sublime Text](https://groups.google.com/forum/#!topic/Golang-nuts/8oCSjAiKXUQ),
|
||||
with better support for other editors in the pipeline.
|
||||
|
||||
Early next year we will release more improvements in Go 1.6, including
|
||||
HTTP/2 support for [net/http](https://golang.org/pkg/net/http/) servers and
|
||||
clients, an official package vendoring mechanism, support for blocks in text
|
||||
and HTML templates, a memory sanitizer that checks both Go and C/C++ code, and
|
||||
the usual assortment of other improvements and fixes.
|
||||
|
||||
This is the sixth time we have had the pleasure of writing a birthday blog post
|
||||
for Go, and we would not be doing so if not for the wonderful and passionate
|
||||
people in our community. The Go team would like to thank everyone who has
|
||||
contributed code, written an open source library, authored a blog post, helped
|
||||
a new gopher, or just given Go a try. Without you, Go would not be as complete,
|
||||
useful, or successful as it is today. Thank you, and celebrate!
|
Двоичные данные
_content/6years/6years-gopher.png
До Ширина: | Высота: | Размер: 18 KiB |
|
@ -1,52 +0,0 @@
|
|||
# Seven years of Go
|
||||
10 Nov 2016
|
||||
Summary: Happy 7th birthday, Go!
|
||||
|
||||
The Go Team
|
||||
rsc@golang.org
|
||||
|
||||
##
|
||||
|
||||
<img src="7years/gopherbelly300.jpg" align="right">
|
||||
|
||||
Today marks seven years since we open-sourced our preliminary sketch of Go.
|
||||
With the help of the open source community, including more than a thousand
|
||||
individual contributors to the Go source repositories,
|
||||
Go has matured into a language used all over the world.
|
||||
|
||||
The most significant user-facing changes to Go over the past year are the
|
||||
addition of built-in support for
|
||||
[HTTP/2](https://www.youtube.com/watch?v=FARQMJndUn0#t=0m0s) in
|
||||
[Go 1.6](https://golang.org/doc/go1.6) and the integration of the
|
||||
[context package](https://blog.golang.org/context) into the standard library in [Go 1.7](https://golang.org/doc/go1.7).
|
||||
But we’ve been making many less visible improvements.
|
||||
Go 1.7 changed the x86-64 compiler to use a new SSA-based back end,
|
||||
improving the performance of most Go programs by 10–20%.
|
||||
For Go 1.8, planned for release next February,
|
||||
we have changed the compilers for the other architectures to use the new back end too.
|
||||
We’ve also added new ports, to Android on 32-bit x86, Linux on 64-bit MIPS,
|
||||
and Linux on IBM z Systems.
|
||||
And we’ve developed new garbage-collection techniques that reduce typical
|
||||
“stop the world” pauses to [under 100 microseconds](https://golang.org/design/17503-eliminate-rescan).
|
||||
(Contrast that with Go 1.5’s big news of [10 milliseconds or less](https://blog.golang.org/go15gc).)
|
||||
|
||||
This year kicked off with a global Go hackathon,
|
||||
the [Gopher Gala](https://blog.golang.org/gophergala), in January.
|
||||
Then there were [Go conferences](https://golang.org/wiki/Conferences) in India and Dubai in February,
|
||||
China and Japan in April, San Francisco in May, Denver in July,
|
||||
London in August, Paris last month, and Brazil this past weekend.
|
||||
And GothamGo in New York is next week.
|
||||
This year also saw more than 30 new [Go user groups](https://golang.org/wiki/GoUserGroups),
|
||||
eight new [Women Who Go](http://www.womenwhogo.org/) chapters,
|
||||
and four [GoBridge](https://golangbridge.org/) workshops around the world.
|
||||
|
||||
We continue to be overwhelmed by and grateful for
|
||||
the enthusiasm and support of the Go community.
|
||||
Whether you participate by contributing changes, reporting bugs,
|
||||
sharing your expertise in design discussions, writing blog posts or books,
|
||||
running meetups, helping others learn or improve,
|
||||
open sourcing Go packages you wrote, or just being part of the Go community,
|
||||
the Go team thanks you for your help, your time, and your energy.
|
||||
Go would not be the success it is today without you.
|
||||
|
||||
Thank you, and here’s to another year of fun and success with Go!
|
Двоичные данные
_content/7years/gopherbelly300.jpg
До Ширина: | Высота: | Размер: 68 KiB |
|
@ -1,160 +0,0 @@
|
|||
# Eight years of Go
|
||||
10 Nov 2017
|
||||
Tags: community, birthday
|
||||
Summary: Happy 8th birthday, Go!
|
||||
|
||||
Steve Francia
|
||||
|
||||
##
|
||||
|
||||
Today we celebrate 8 years since Go was released as an open source project.
|
||||
During [Go’s 4th anniversary](https://blog.golang.org/4years), Andrew
|
||||
finished the post with “Here's to four more years!”. Now that we have reached
|
||||
that milestone, I cannot help but reflect on how much the project and
|
||||
ecosystem has grown since then. In our post 4 years ago we included a chart
|
||||
demonstrating Go's rising popularity on Google Trends with the search term
|
||||
"golang". Today, we’re including an updated chart. In this relative scale of
|
||||
popularity, what was 100 four years ago is now a mere 17. Go’s popularity has
|
||||
increased exponentially over the last 8 years and continues to grow.
|
||||
|
||||
.image 8years/image1.png
|
||||
|
||||
Source: [trends.google.com](https://trends.google.com/trends/explore?date=2009-10-01%202017-10-30&q=golang&hl=en-US)
|
||||
|
||||
## Developers love Go
|
||||
|
||||
Go has been embraced by developers all over the world with approximately one
|
||||
million users worldwide. In the [freshly published 2017 Octoverse](https://octoverse.github.com/)
|
||||
by GitHub, **Go has become the #9 most popular language**, surpassing C.
|
||||
**Go is the fastest growing language on GitHub in 2017** in the top 10 with
|
||||
**52% growth over the previous year**. In growth, Go swapped places with
|
||||
Javascript, which fell to the second spot with 44%.
|
||||
|
||||
.image 8years/image2.png
|
||||
|
||||
Source: [octoverse.github.com](https://octoverse.github.com/)
|
||||
|
||||
In [Stack Overflow's 2017 developer survey](https://insights.stackoverflow.com/survey/2017#most-loved-dreaded-and-wanted)
|
||||
, Go was the only language that was both on the **top 5 most loved and top 5 most wanted** languages.
|
||||
People who use Go, love it, and the people who aren’t using Go, want to be.
|
||||
|
||||
.image 8years/image3.png
|
||||
.image 8years/image4.png
|
||||
|
||||
Source: [insights.stackoverflow.com/survey/2017](https://insights.stackoverflow.com/survey/2017#most-loved-dreaded-and-wanted)
|
||||
|
||||
## Go: The language of Cloud Infrastructure
|
||||
|
||||
In 2014, analyst Donnie Berkholz called Go
|
||||
[the emerging language of cloud infrastructure](http://redmonk.com/dberkholz/2014/03/18/go-the-emerging-language-of-cloud-infrastructure/).
|
||||
**By 2017, Go has emerged as the language of cloud infrastructure**.
|
||||
Today, **every single cloud company has critical components of their cloud infrastructure implemented in Go**
|
||||
including Google Cloud, AWS, Microsoft Azure, Digital Ocean, Heroku and many others. Go
|
||||
is a key part of cloud companies like Alibaba, Cloudflare, and Dropbox. Go is
|
||||
a critical part of open infrastructure including Kubernetes, Cloud Foundry,
|
||||
Openshift, NATS, Docker, Istio, Etcd, Consul, Juju and many more. Companies
|
||||
are increasingly choosing Go to build cloud infrastructure solutions.
|
||||
|
||||
## Go’s Great Community
|
||||
|
||||
It may be hard to imagine that only four years ago the Go community was
|
||||
transitioning from online-only to include in-person community with its first
|
||||
conference. Now the Go community has had over 30 conferences all around the
|
||||
world with hundreds of presentations and tens of thousands of attendees.
|
||||
There are hundreds of Go meetups meeting monthly covering much of the globe.
|
||||
Wherever you live, you are likely to find a Go meetup nearby.
|
||||
|
||||
Two different organizations have been established to help with inclusivity in
|
||||
the Go community, Go Bridge and Women Who Go; the latter has grown to over 25
|
||||
chapters. Both have been instrumental in offering free trainings. In 2017
|
||||
alone over 50 scholarships to conferences have been given through efforts of
|
||||
Go Bridge and Women Who Go.
|
||||
|
||||
This year we had two significant firsts for the Go project. We had our first
|
||||
[contributor summit](https://blog.golang.org/contributors-summit) where
|
||||
people from across the Go community came together to
|
||||
discuss the needs and future of the Go project. Shortly after, we had the
|
||||
first [Go contributor workshop](https://blog.golang.org/contributor-workshop)
|
||||
where hundreds of people came to make their first Go contribution.
|
||||
|
||||
.image 8years/photo.jpg
|
||||
|
||||
Photo by Sameer Ajmani
|
||||
|
||||
## Go’s impact on open source
|
||||
|
||||
Go has become a major force in the world of open source powering some of the
|
||||
most popular projects and enabling innovations across many industries. Find
|
||||
thousands of additional applications and libraries at [awesome-go](https://github.com/avelino/awesome-go). Here are
|
||||
just a handful of the most popular:
|
||||
|
||||
- [Moby](https://mobyproject.org/) (formerly Docker) is a tool for packaging
|
||||
and running applications in lightweight containers.
|
||||
Its creator Solomon Hykes cited Go's standard library,
|
||||
concurrency primitives, and ease of deployment as key factors,
|
||||
and said "To put it simply, if Docker had not been written in Go,
|
||||
it would not have been as successful."
|
||||
|
||||
- [Kubernetes](https://kubernetes.io/) is a system for automating deployment,
|
||||
scaling and management of containerized applications.
|
||||
Initially designed by Google and used in the Google cloud,
|
||||
Kubernetes now is a critical part of every major cloud offering.
|
||||
|
||||
- [Hugo](https://gohugo.io/) is now the most popular open-source static website engine.
|
||||
With its amazing speed and flexibility, Hugo makes building websites fun again.
|
||||
According to [w3techs](https://w3techs.com/technologies/overview/content_management/all),
|
||||
Hugo now has nearly 3x the usage of Jekyll, the former leader.
|
||||
|
||||
- [Prometheus](https://prometheus.io/) is an open source monitoring solution
|
||||
and time series database that powers metrics and alerting designed to be
|
||||
the system you go to during an outage to allow you to quickly diagnose problems.
|
||||
|
||||
- [Grafana](https://grafana.com/) is an open source,
|
||||
feature-rich metrics dashboard and graph editor for Graphite,
|
||||
Elasticsearch, OpenTSDB, Prometheus and InfluxDB.
|
||||
|
||||
- [Lantern](https://getlantern.org/) delivers fast, reliable and secure access to blocked websites and apps.
|
||||
|
||||
- [Syncthing](https://syncthing.net/) is an open-source cross platform
|
||||
peer-to-peer continuous file synchronization application
|
||||
|
||||
- [Keybase](https://keybase.io/) is a new and free security app for mobile
|
||||
phones and computers.
|
||||
Think of it as an open source Dropbox & Slack with end-to-end encryption
|
||||
public-key cryptography.
|
||||
|
||||
- [Fzf](https://github.com/junegunn/fzf) is an interactive Unix filter
|
||||
for command-line that can be used with any list;
|
||||
files, command history, processes, hostnames,
|
||||
bookmarks, git commits, etc.
|
||||
Fzf supports Unix, macOS and has beta support for Windows.
|
||||
It also can operate as a vim plugin.
|
||||
|
||||
Many of these authors have said that their projects would not exist without
|
||||
Go. Some like Kubernetes and Docker created entirely new solutions. Others
|
||||
like Hugo, Syncthing and Fzf created more refined experiences where many
|
||||
solutions already existed. The popularity of these applications alone is
|
||||
proof that Go is a ideal language for a broad set of use cases.
|
||||
|
||||
## Thank You
|
||||
|
||||
This is the eighth time we have had the pleasure of writing a birthday blog
|
||||
post for Go and we continue to be overwhelmed by and grateful for the
|
||||
enthusiasm and support of the Go community.
|
||||
|
||||
Since Go was first open sourced we have had 10 releases of the language,
|
||||
libraries and tooling with more than 1680 contributors making over 50,000
|
||||
commits to the project's 34 repositories; More than double the number of
|
||||
contributors and nearly double the number of commits from only [two years ago](https://blog.golang.org/6years).
|
||||
This year we announced that we have begun planning [Go 2](https://blog.golang.org/toward-go2), our first major
|
||||
revision of the language and tooling.
|
||||
|
||||
The Go team would like to thank everyone who has contributed to the project,
|
||||
whether you participate by contributing changes, reporting bugs, sharing your
|
||||
expertise in design discussions, writing blog posts or books, running events,
|
||||
attending or speaking at events, helping others learn or improve, open
|
||||
sourcing Go packages you wrote, contributing artwork, introducing Go to
|
||||
someone, or being part of the Go community. Without you, Go would not be as
|
||||
complete, useful, or successful as it is today.
|
||||
|
||||
Thank you, and here’s to eight more years!
|
Двоичные данные
_content/8years/image1.png
До Ширина: | Высота: | Размер: 40 KiB |
Двоичные данные
_content/8years/image2.png
До Ширина: | Высота: | Размер: 86 KiB |
Двоичные данные
_content/8years/image3.png
До Ширина: | Высота: | Размер: 28 KiB |
Двоичные данные
_content/8years/image4.png
До Ширина: | Высота: | Размер: 16 KiB |
Двоичные данные
_content/8years/photo.jpg
До Ширина: | Высота: | Размер: 1.1 MiB |
|
@ -1,100 +0,0 @@
|
|||
# Nine years of Go
|
||||
10 Nov 2018
|
||||
Tags: community, birthday
|
||||
Summary: Happy 9th birthday, Go!
|
||||
|
||||
Steve Francia
|
||||
|
||||
## Introduction
|
||||
|
||||
Today marks the ninth anniversary of the day we open-sourced our initial sketch of Go.
|
||||
On each anniversary we like to take time to reflect on what has happened over the past year.
|
||||
The past 12 months have been a breakout year for the Go language and community.
|
||||
|
||||
## Go Love & Adoption
|
||||
|
||||
Thanks to all of you, 2018 was an amazing year for Go!
|
||||
In multiple industry surveys Gophers expressed how happy they were using Go,
|
||||
and many non-Go developers indicated they intended to learn Go before any other language.
|
||||
|
||||
In [Stack Overflow’s 2018 Developer Survey](https://insights.stackoverflow.com/survey/2018#most-loved-dreaded-and-wanted),
|
||||
Go retained its coveted spot in both the top 5 most loved and top 5 most wanted languages.
|
||||
People who use Go love it, and people who aren’t using Go want to.
|
||||
|
||||
In [ActiveState’s 2018 Developer Survey](https://www.activestate.com/developer-survey-2018-open-source-runtime-pains),
|
||||
Go topped the charts with 36% of users responding they were “Extremely Satisfied” using Go
|
||||
and 61% responding “Very Satisfied” or better.
|
||||
|
||||
[JetBrains’s 2018 Developer Survey](https://www.jetbrains.com/research/devecosystem-2018/) awarded Go
|
||||
the “Most promising language” with 12% of respondents using Go today and 16% intending to use Go in the future.
|
||||
|
||||
In [HackerRank’s 2018 Developer Survey](https://research.hackerrank.com/developer-skills/2018/),
|
||||
38% of developers responded that they were intending to learn Go next.
|
||||
|
||||
We are excited about all of our new gophers and actively working to improve our educational and community resources.
|
||||
|
||||
## Go Community
|
||||
|
||||
It’s hard to believe that it’s only been five years since
|
||||
the first Go conferences and Go meetups.
|
||||
We’ve seen major growth in this area of community leadership over the last year.
|
||||
There are now over 20 [Go conferences](https://github.com/golang/go/wiki/Conferences)
|
||||
and over 300 [Go-related meetups](https://www.meetup.com/topics/golang/) spanning the globe.
|
||||
|
||||
Thanks to the hard work put into these many conferences and meetups,
|
||||
there have been hundreds of great talks this year.
|
||||
Here are a few of our favorite talks specifically discussing the growth of our community
|
||||
and how we can better support gophers worldwide.
|
||||
|
||||
- [Writing Accessible Go](https://www.youtube.com/watch?v=cVaDY0ChvOQ), by Julia Ferraioli at GopherCon
|
||||
- [The Importance of Beginners](https://www.youtube.com/watch?v=7yMXs9TRvVI), by Natalie Pistunovich at GopherCon
|
||||
- [The Legacy of Go, Part 2](https://www.youtube.com/watch?v=I_KcpgxcFyU), by Carmen Andoh at GothamGo
|
||||
- [Growing a Community of Gophers](https://www.youtube.com/watch?v=dl1mCGKwlYY), by Cassandra Salisbury at Gopherpalooza
|
||||
|
||||
On that theme, this year we also [revised our code of conduct](https://blog.golang.org/conduct-2018)
|
||||
to better support inclusivity in the Go community.
|
||||
|
||||
The Go community is truly global.
|
||||
At GopherCon Europe in Iceland this past summer, gophers literally spanned the gap between the continents.
|
||||
|
||||
.image 9years/9years-iceland.jpg _ 800
|
||||
|
||||
_(Photo by Winter Francia.)_
|
||||
|
||||
## Go 2
|
||||
|
||||
After five years of experience with Go 1, we’ve started looking at
|
||||
what we should change about Go to better support
|
||||
[programming at scale](https://talks.golang.org/2012/splash.article).
|
||||
|
||||
Last spring, we published a [draft design for Go modules](https://blog.golang.org/versioning-proposal),
|
||||
which provide an integrated mechanism for versioning and package distribution.
|
||||
The most recent Go release, Go 1.11, included
|
||||
[preliminary support for modules](https://golang.org/doc/go1.11#modules).
|
||||
|
||||
Last summer we published
|
||||
[early draft designs](https://blog.golang.org/go2draft)
|
||||
for how Go 2 might better support error values, error handling, and generic programming.
|
||||
|
||||
We are excited about refining these designs with the community’s help as we work
|
||||
[toward Go 2](https://blog.golang.org/toward-go2).
|
||||
|
||||
## Go Contributors
|
||||
|
||||
The Go project has been increasing in the number of contributions from the community for several years.
|
||||
The project hit a major milestone in mid-2018 when, for the first time,
|
||||
we had more contributions coming from the community than the Go team.
|
||||
|
||||
.image 9years/9years-graph.png _ 600
|
||||
|
||||
## Thank You
|
||||
|
||||
On a personal note, from the entire Go team,
|
||||
we want to sincerely thank all of you.
|
||||
We feel privileged to be able to work on the Go project
|
||||
and are grateful to the many gophers around the world who have joined us.
|
||||
|
||||
We are especially thankful for the thousands of volunteers
|
||||
who help through mentorship, organizing, contributing,
|
||||
and supporting your fellow gophers.
|
||||
You have made Go what it is today.
|
Двоичные данные
_content/9years/9years-graph.png
До Ширина: | Высота: | Размер: 54 KiB |
Двоичные данные
_content/9years/9years-iceland.jpg
До Ширина: | Высота: | Размер: 67 KiB |
|
@ -1,27 +0,0 @@
|
|||
This directory holds Go blog articles, in *.article.
|
||||
See https://pkg.go.dev/golang.org/x/tools/present?tab=doc
|
||||
for documentation of the file format or look at any of the
|
||||
articles for examples.
|
||||
|
||||
Article file names should be short, amenable to being typed by hand in URLs.
|
||||
Typically article file names are up to three words, separated by dashes.
|
||||
A trailing year in the name typically does not have a dash before it.
|
||||
|
||||
All supporting files for an article, even if there's only one, should be
|
||||
placed in a directory named for the article (minus the .article suffix).
|
||||
|
||||
If your article has code that is meant to be a working program, please use
|
||||
.code, or ideally .play, to load the lines from a supporting .go file.
|
||||
That way you can easily check that the .go file, and therefore the code
|
||||
in your article, still works.
|
||||
|
||||
Please use .image and .video to embed images and videos,
|
||||
instead of using raw HTML tags. The .image and .video commands
|
||||
provide a way to adjust the implementation of those embeddings
|
||||
all in one place.
|
||||
|
||||
Please use .html when it is necessary to add large blocks of HTML,
|
||||
keeping article text in the main .article file. Another important use of
|
||||
.html is to factor out an HTML snippet that appears multiple times.
|
||||
Short HTML sequences, like <div><center> or </div></center>,
|
||||
are fine to put directly in the article files.
|
|
@ -1,44 +0,0 @@
|
|||
# Go App Engine SDK 1.5.5 released
|
||||
11 Oct 2011
|
||||
Tags: appengine, gofix, release
|
||||
Summary: Go App Engine SDK 1.5.5 includes Go release.r60.2.
|
||||
OldURL: /go-app-engine-sdk-155-released
|
||||
|
||||
Andrew Gerrand
|
||||
|
||||
##
|
||||
|
||||
Today we released version 1.5.5 the Go App Engine SDK.
|
||||
You can download it from the [App Engine downloads page](http://code.google.com/appengine/downloads.html).
|
||||
|
||||
This release includes changes and improvements to the App Engine APIs and
|
||||
brings the supporting Go tool chain to [release.r60.2](https://golang.org/doc/devel/release.html#r60)
|
||||
(the current stable release).
|
||||
Also included in this release are the [godoc](https://golang.org/cmd/godoc/),
|
||||
[gofmt](https://golang.org/cmd/gofmt/),
|
||||
and [gofix](https://golang.org/cmd/gofix/) tools from the Go tool chain.
|
||||
They can be found in the root directory of the SDK.
|
||||
|
||||
Some changes made in this release are backwards-incompatible,
|
||||
so we have incremented the SDK `api_version` to 3.
|
||||
Existing apps will require code changes when migrating to `api_version` 3.
|
||||
|
||||
The gofix tool that ships with the SDK has been customized with App Engine-specific modules.
|
||||
It can be used to automatically update Go apps to work with the latest appengine
|
||||
packages and the updated Go standard library.
|
||||
To update your apps, run:
|
||||
|
||||
/path/to/sdk/gofix /path/to/your/app
|
||||
|
||||
The SDK now includes the appengine package source code,
|
||||
so you can use the local godoc to read App Engine API documentation:
|
||||
|
||||
/path/to/sdk/godoc appengine/datastore Get
|
||||
|
||||
**Important note:** We have deprecated `api_version` 2.
|
||||
Go apps that use `api_version` 2 will stop working after 16 December 2011.
|
||||
Please update your apps to use `api_version` 3 before then.
|
||||
|
||||
See the [release notes](http://code.google.com/p/googleappengine/wiki/SdkForGoReleaseNotes)
|
||||
for a full list of changes.
|
||||
Please direct any questions about the new SDK to the [Go App Engine discussion group](http://groups.google.com/group/google-appengine-go).
|
|
@ -1,45 +0,0 @@
|
|||
# Go updates in App Engine 1.7.1
|
||||
22 Aug 2012
|
||||
Tags: appengine, release
|
||||
Summary: App Engine SDK 1.7.1 adds memcache and other functionality for Go.
|
||||
OldURL: /go-updates-in-app-engine-171
|
||||
|
||||
Andrew Gerrand
|
||||
|
||||
##
|
||||
|
||||
This week we released version 1.7.1 of the App Engine SDK.
|
||||
It includes some significant updates specific to the App Engine runtime for Go.
|
||||
|
||||
The [memcache package](https://developers.google.com/appengine/docs/go/memcache/reference) has
|
||||
had some additions to its [Codec](https://developers.google.com/appengine/docs/go/memcache/reference#Codec) convenience type.
|
||||
The SetMulti, AddMulti, CompareAndSwap, and CompareAndSwapMulti methods
|
||||
make it easier to store and update encoded data in the [Memcache Service](https://developers.google.com/appengine/docs/go/memcache/overview).
|
||||
|
||||
The [bulkloader tool](https://developers.google.com/appengine/docs/go/tools/uploadingdata) can
|
||||
now be used with Go apps,
|
||||
allowing users to upload and download datastore records in bulk.
|
||||
This is useful for backups and offline processing,
|
||||
and a great help when migrating Python or Java apps to the Go runtime.
|
||||
|
||||
The [Images Service](https://developers.google.com/appengine/docs/go/images/overview) is
|
||||
now available to Go users.
|
||||
The new [appengine/image package](https://developers.google.com/appengine/docs/go/images/reference) supports serving
|
||||
images directly from Blobstore and resizing or cropping those images on the fly.
|
||||
Note that this is not the full image service as provided by the Python and Java SDKs,
|
||||
as much of the equivalent functionality is available in the [standard Go image package](https://golang.org/pkg/image/) and
|
||||
external packages such as [graphics-go](http://code.google.com/p/graphics-go/).
|
||||
|
||||
The new [runtime.RunInBackground](https://developers.google.com/appengine/docs/go/backends/runtime#RunInBackground) function
|
||||
allows backend requests to spawn a new request independent of the initial request.
|
||||
These can run in the background as long as the backend stays alive.
|
||||
|
||||
Finally, we have filled in some missing functionality:
|
||||
the [xmpp package](https://developers.google.com/appengine/docs/go/xmpp/reference) now
|
||||
supports sending presence updates and chat invitations and retrieving the
|
||||
presence state of another user,
|
||||
and the [user package](https://developers.google.com/appengine/docs/go/users/reference) supports
|
||||
authenticating clients with OAuth.
|
||||
|
||||
You can grab the new SDK from the [App Engine downloads page](https://developers.google.com/appengine/downloads#Google_App_Engine_SDK_for_Go) and
|
||||
browse the [updated documentation](https://developers.google.com/appengine/docs/go).
|
|
@ -1,111 +0,0 @@
|
|||
# Go on App Engine: tools, tests, and concurrency
|
||||
13 Dec 2013
|
||||
Tags: appengine
|
||||
Summary: Announcing improvements to Go on App Engine.
|
||||
|
||||
Andrew Gerrand
|
||||
|
||||
Johan Euphrosine
|
||||
|
||||
## Background
|
||||
|
||||
When we [launched Go for App Engine](https://blog.golang.org/go-and-google-app-engine)
|
||||
in May 2011 the SDK was just a modified version of the Python SDK.
|
||||
At the time, there was no canonical way to build or organize Go programs, so it
|
||||
made sense to take the Python approach. Since then Go 1.0 was released,
|
||||
including the [go tool](https://golang.org/cmd/go/) and a
|
||||
[convention](https://golang.org/doc/code.html) for organizing Go programs.
|
||||
|
||||
In January 2013 we announced
|
||||
[better integration](https://blog.golang.org/the-app-engine-sdk-and-workspaces-gopath)
|
||||
between the Go App Engine SDK and the go tool, promoting the use of
|
||||
conventional import paths in App Engine apps and making it possible to use "go
|
||||
get" to fetch app dependencies.
|
||||
|
||||
With the recent release of App Engine 1.8.8 we are pleased to announce more
|
||||
improvements to the developer experience for Go on App Engine.
|
||||
|
||||
## The goapp tool
|
||||
|
||||
The Go App Engine SDK now includes the "goapp" tool, an App Engine-specific
|
||||
version of the "go" tool. The new name permits users to keep both the regular
|
||||
"go" tool and the "goapp" tool in their system PATH.
|
||||
|
||||
In addition to the existing "go" tool [commands](https://golang.org/cmd/go/),
|
||||
the "goapp" tool provides new commands for working with App Engine apps.
|
||||
The "[goapp serve](https://developers.google.com/appengine/docs/go/tools/devserver)"
|
||||
command starts the local development server and the
|
||||
"[goapp deploy](https://developers.google.com/appengine/docs/go/tools/uploadinganapp)"
|
||||
command uploads an app to App Engine.
|
||||
|
||||
The main advantages offered by the "goapp serve" and "goapp deploy" commands
|
||||
are a simplified user interface and consistency with existing commands like
|
||||
"go get" and "go fmt".
|
||||
For example, to run a local instance of the app in the current directory, run:
|
||||
|
||||
$ goapp serve
|
||||
|
||||
To upload it to App Engine:
|
||||
|
||||
$ goapp deploy
|
||||
|
||||
You can also specify the Go import path to serve or deploy:
|
||||
|
||||
$ goapp serve github.com/user/myapp
|
||||
|
||||
You can even specify a YAML file to serve or deploy a specific
|
||||
[module](https://developers.google.com/appengine/docs/go/modules/):
|
||||
|
||||
$ goapp deploy mymodule.yaml
|
||||
|
||||
These commands can replace most uses of `dev_appserver.py` and `appcfg.py`,
|
||||
although the Python tools are still available for their less common uses.
|
||||
|
||||
## Local unit testing
|
||||
|
||||
The Go App Engine SDK now supports local unit testing, using Go's native
|
||||
[testing package](https://developers.google.com/appengine/docs/go/tools/localunittesting)
|
||||
and the "[go test](https://golang.org/cmd/go/#hdr-Test_packages)" command
|
||||
(provided as "goapp test" by the SDK).
|
||||
|
||||
Furthermore, you can now write tests that use App Engine services.
|
||||
The [aetest package](https://developers.google.com/appengine/docs/go/tools/localunittesting#Go_Introducing_the_aetest_package)
|
||||
provides an appengine.Context value that delegates requests to a temporary
|
||||
instance of the development server.
|
||||
|
||||
For more information about using "goapp test" and the aetest package, see the
|
||||
[Local Unit Testing for Go documentation](https://developers.google.com/appengine/docs/go/tools/localunittesting).
|
||||
Note that the aetest package is still in its early days;
|
||||
we hope to add more features over time.
|
||||
|
||||
## Better concurrency support
|
||||
|
||||
It is now possible to configure the number of concurrent requests served by
|
||||
each of your app's dynamic instances by setting the
|
||||
[`max_concurrent_requests`](https://developers.google.com/appengine/docs/go/modules/#max_concurrent_requests) option
|
||||
(available to [Automatic Scaling modules](https://developers.google.com/appengine/docs/go/modules/#automatic_scaling) only).
|
||||
|
||||
Here's an example `app.yaml` file:
|
||||
|
||||
application: maxigopher
|
||||
version: 1
|
||||
runtime: go
|
||||
api_version: go1
|
||||
automatic_scaling:
|
||||
max_concurrent_requests: 100
|
||||
|
||||
This configures each instance of the app to serve up to 100 requests
|
||||
concurrently (up from the default of 10). You can configure Go instances to
|
||||
serve up to a maximum of 500 concurrent requests.
|
||||
|
||||
This setting allows your instances to handle more simultaneous requests by
|
||||
taking advantage of Go's efficient handling of concurrency, which should yield
|
||||
better instance utilization and ultimately fewer billable instance hours.
|
||||
|
||||
## Conclusion
|
||||
|
||||
With these changes Go on App Engine is more convenient and efficient than ever,
|
||||
and we hope you enjoy the improvements. Please join the
|
||||
[google-appengine-go group](http://groups.google.com/group/google-appengine-go/)
|
||||
to raise questions or discuss these changes with the engineering team and the
|
||||
rest of the community.
|
|
@ -1,36 +0,0 @@
|
|||
# Go for App Engine is now generally available
|
||||
21 Jul 2011
|
||||
Tags: appengine, release
|
||||
Summary: You can use Go on App Engine now!
|
||||
OldURL: /go-for-app-engine-is-now-generally
|
||||
|
||||
Andrew Gerrand
|
||||
|
||||
##
|
||||
|
||||
The Go and App Engine teams are excited to announce that the Go runtime
|
||||
for App Engine is now generally available.
|
||||
This means you can take that Go app you've been working on (or meaning to
|
||||
work on) and deploy it to App Engine right now with the new [1.5.2 SDK](http://code.google.com/appengine/downloads.html).
|
||||
|
||||
Since we announced the Go runtime at Google I/O we have continued to [improve and extend](http://code.google.com/p/googleappengine/wiki/SdkForGoReleaseNotes)
|
||||
Go support for the App Engine APIs and have added the Channels API.
|
||||
The Go Datastore API now supports transactions and ancestor queries, too.
|
||||
See the [Go App Engine documentation](https://code.google.com/appengine/docs/go/)
|
||||
for all the details.
|
||||
|
||||
For those who have been using the Go SDK already,
|
||||
please note that the 1.5.2 release introduces `api_version` 2.
|
||||
This is because the new SDK is based on Go `release.r58.1` (the current
|
||||
stable version of Go) and is not backwards compatible with the previous release.
|
||||
Existing apps may require changes as per the [r58 release notes](https://golang.org/doc/devel/release.html#r58).
|
||||
Once you've updated your code, you should redeploy your app with the line
|
||||
`api_version: 2` in its `app.yaml` file.
|
||||
Apps written against `api_version` 1 will stop working after the 18th of August.
|
||||
|
||||
Finally, we owe a huge thanks to our trusted testers and their many bug reports.
|
||||
Their help was invaluable in reaching this important milestone.
|
||||
|
||||
_The fastest way to get started with Go on App Engine is with the_ [_Getting Started guide_](http://code.google.com/appengine/docs/go/gettingstarted/).
|
||||
|
||||
_Note that the Go runtime is still considered experimental; it is not as well-supported as the Python and Java runtimes._
|
|
@ -1,77 +0,0 @@
|
|||
# Announcing App Engine’s New Go 1.11 Runtime
|
||||
16 Oct 2018
|
||||
Tags: appengine
|
||||
Summary: Google Cloud is announcing a new Go 1.11 runtime for App Engine, with fewer limits on app structure.
|
||||
|
||||
Eno Compton
|
||||
|
||||
Tyler Bui-Palsulich
|
||||
|
||||
##
|
||||
|
||||
[App Engine](https://cloud.google.com/appengine/) launched
|
||||
[experimental support for Go](https://blog.golang.org/go-and-google-app-engine)
|
||||
in 2011. In the subsequent years, the Go community has grown significantly and
|
||||
has settled on idiomatic
|
||||
patterns for cloud-based applications. Today, Google Cloud is
|
||||
[announcing a new Go 1.11 runtime](https://cloud.google.com/blog/products/application-development/go-1-11-is-now-available-on-app-engine)
|
||||
for the App Engine standard environment that provides all the
|
||||
power of App Engine—things like paying only for what you use, automatic scaling,
|
||||
and managed infrastructure—while supporting idiomatic Go.
|
||||
|
||||
Starting with Go 1.11, Go on App Engine has no limits on application structure,
|
||||
supported packages, `context.Context` values, or HTTP clients. Write your Go
|
||||
application however you prefer, add an `app.yaml` file, and your app is ready
|
||||
to deploy on App Engine.
|
||||
[Specifying Dependencies](https://cloud.google.com/appengine/docs/standard/go111/specifying-dependencies)
|
||||
describes how the new runtime
|
||||
supports [vendoring](https://golang.org/cmd/go/#hdr-Vendor_Directories) and
|
||||
[modules](https://golang.org/doc/go1.11#modules) (experimental) for dependency
|
||||
management.
|
||||
|
||||
Along with [Cloud Functions support for Go](https://twitter.com/kelseyhightower/status/1035278586754813952)
|
||||
(more on that in a future post), App Engine provides a compelling way to run Go
|
||||
code on Google Cloud Platform (GCP) with no concern for the underlying
|
||||
infrastructure.
|
||||
|
||||
Let’s take a look at creating a small application for App Engine. For the
|
||||
example here, we assume a `GOPATH`-based workflow, although Go modules have
|
||||
[experimental support](https://cloud.google.com/appengine/docs/standard/go111/specifying-dependencies)
|
||||
as well.
|
||||
|
||||
First, you create the application in your `GOPATH`:
|
||||
|
||||
.code appengine/main.go
|
||||
|
||||
The code contains an idiomatic setup for a small HTTP server that responds with
|
||||
“Hello, 世界.” If you have previous App Engine experience, you’ll notice the
|
||||
absence of any call to `appengine.Main()`, which is now entirely optional.
|
||||
Furthermore, the application code is completely portable—there are no ties to
|
||||
the infrastructure that your application is deployed on.
|
||||
|
||||
If you need to use external dependencies, you can add those dependencies to a
|
||||
`vendor` directory or to a `go.mod` file, both of which the new runtime
|
||||
supports.
|
||||
|
||||
With the application code complete, create an `app.yaml` file to specify
|
||||
the runtime:
|
||||
|
||||
runtime: go111
|
||||
|
||||
Finally, set your machine up with a Google Cloud Platform account:
|
||||
|
||||
- Create an account with [https://cloud.google.com](GCP).
|
||||
- [Create a project](https://cloud.google.com/resource-manager/docs/creating-managing-projects).
|
||||
- Install the [Cloud SDK](https://cloud.google.com/sdk/) on your system.
|
||||
|
||||
With all the setup complete, you can deploy using one command:
|
||||
|
||||
gcloud app deploy
|
||||
|
||||
We think Go developers will find the new Go 1.11 runtime for App Engine an
|
||||
exciting addition to the available options to run Go applications. There is a
|
||||
[free tier](https://cloud.google.com/free/). Check out the
|
||||
[getting started guide](https://cloud.google.com/appengine/docs/standard/go111/building-app/)
|
||||
or the
|
||||
[migration guide](https://cloud.google.com/appengine/docs/standard/go111/go-differences)
|
||||
and deploy an app to the new runtime today!
|
|
@ -1,157 +0,0 @@
|
|||
# The App Engine SDK and workspaces (GOPATH)
|
||||
9 Jan 2013
|
||||
Tags: appengine, tools, gopath
|
||||
Summary: App Engine SDK 1.7.4 adds support for GOPATH-style workspaces.
|
||||
OldURL: /the-app-engine-sdk-and-workspaces-gopath
|
||||
|
||||
Andrew Gerrand
|
||||
|
||||
## Introduction
|
||||
|
||||
When we released Go 1 we introduced the [go tool](https://golang.org/cmd/go/) and,
|
||||
with it, the concept of workspaces.
|
||||
Workspaces (specified by the GOPATH environment variable) are a convention
|
||||
for organizing code that simplifies fetching,
|
||||
building, and installing Go packages.
|
||||
If you're not familiar with workspaces, please read [this article](https://golang.org/doc/code.html)
|
||||
or watch [this screencast](http://www.youtube.com/watch?v=XCsL89YtqCs) before reading on.
|
||||
|
||||
Until recently, the tools in the App Engine SDK were not aware of workspaces.
|
||||
Without workspaces the "[go get](https://golang.org/cmd/go/#hdr-Download_and_install_packages_and_dependencies)"
|
||||
command cannot function,
|
||||
and so app authors had to install and update their app dependencies manually. It was a pain.
|
||||
|
||||
This has all changed with version 1.7.4 of the App Engine SDK.
|
||||
The [dev\_appserver](https://developers.google.com/appengine/docs/go/tools/devserver)
|
||||
and [appcfg](https://developers.google.com/appengine/docs/go/tools/uploadinganapp)
|
||||
tools are now workspace-aware.
|
||||
When running locally or uploading an app,
|
||||
these tools now search for dependencies in the workspaces specified by the
|
||||
GOPATH environment variable.
|
||||
This means you can now use "go get" while building App Engine apps,
|
||||
and switch between normal Go programs and App Engine apps without changing
|
||||
your environment or habits.
|
||||
|
||||
For example, let's say you want to build an app that uses OAuth 2.0 to authenticate
|
||||
with a remote service.
|
||||
A popular OAuth 2.0 library for Go is the [oauth2](https://godoc.org/golang.org/x/oauth2) package,
|
||||
which you can install to your workspace with this command:
|
||||
|
||||
go get golang.org/x/oauth2
|
||||
|
||||
When writing your App Engine app, import the oauth package just as you would in a regular Go program:
|
||||
|
||||
import "golang.org/x/oauth2"
|
||||
|
||||
Now, whether running your app with the dev\_appserver or deploying it with appcfg,
|
||||
the tools will find the oauth package in your workspace. It just works.
|
||||
|
||||
## Hybrid stand-alone/App Engine apps
|
||||
|
||||
The Go App Engine SDK builds on Go's standard [net/http](https://golang.org/pkg/net/http/)
|
||||
package to serve web requests and,
|
||||
as a result, many Go web servers can be run on App Engine with only a few changes.
|
||||
For example, [godoc](https://golang.org/cmd/godoc/) is included in the
|
||||
Go distribution as a stand-alone program,
|
||||
but it can also run as an App Engine app (godoc serves [golang.org](https://golang.org/) from App Engine).
|
||||
|
||||
But wouldn't it be nice if you could write a program that is both a stand-alone
|
||||
web server and an App Engine app? By using [build constraints](https://golang.org/pkg/go/build/#hdr-Build_Constraints), you can.
|
||||
|
||||
Build constraints are line comments that determine whether a file should
|
||||
be included in a package.
|
||||
They are most often used in code that handles a variety of operating systems
|
||||
or processor architectures.
|
||||
For instance, the [path/filepath](https://golang.org/pkg/path/filepath/)
|
||||
package includes the file [symlink.go](https://golang.org/src/pkg/path/filepath/symlink.go),
|
||||
which specifies a build constraint to ensure that it is not built on Windows
|
||||
systems (which do not have symbolic links):
|
||||
|
||||
// +build !windows
|
||||
|
||||
The App Engine SDK introduces a new build constraint term: "appengine". Files that specify
|
||||
|
||||
// +build appengine
|
||||
|
||||
will be built by the App Engine SDK and ignored by the go tool. Conversely, files that specify
|
||||
|
||||
// +build !appengine
|
||||
|
||||
are ignored by the App Engine SDK, while the go tool will happily build them.
|
||||
|
||||
The [goprotobuf](http://code.google.com/p/goprotobuf/) library uses this
|
||||
mechanism to provide two implementations of a key part of its encode/decode machinery:
|
||||
[pointer\_unsafe.go](http://code.google.com/p/goprotobuf/source/browse/proto/pointer_unsafe.go)
|
||||
is the faster version that cannot be used on App Engine because it uses
|
||||
the [unsafe package](https://golang.org/pkg/unsafe/),
|
||||
while [pointer\_reflect.go](http://code.google.com/p/goprotobuf/source/browse/proto/pointer_reflect.go)
|
||||
is a slower version that avoids unsafe by using the [reflect package](https://golang.org/pkg/reflect/) instead.
|
||||
|
||||
Let's take a simple Go web server and turn it into a hybrid app. This is main.go:
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func main() {
|
||||
http.HandleFunc("/", handler)
|
||||
http.ListenAndServe("localhost:8080", nil)
|
||||
}
|
||||
|
||||
func handler(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprint(w, "Hello!")
|
||||
}
|
||||
|
||||
Build this with the go tool and you'll get a stand-alone web server executable.
|
||||
|
||||
The App Engine infrastructure provides its own main function that runs its
|
||||
equivalent to ListenAndServe.
|
||||
To convert main.go to an App Engine app, drop the call to ListenAndServe
|
||||
and register the handler in an init function (which runs before main). This is app.go:
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func init() {
|
||||
http.HandleFunc("/", handler)
|
||||
}
|
||||
|
||||
func handler(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprint(w, "Hello!")
|
||||
}
|
||||
|
||||
To make this a hybrid app, we need to split it into an App Engine-specific part,
|
||||
an stand-alone binary-specific part, and the parts common to both versions.
|
||||
In this case, there is no App Engine-specific part,
|
||||
so we split it into just two files:
|
||||
|
||||
app.go specifies and registers the handler function.
|
||||
It is identical to the code listing above,
|
||||
and requires no build constraints as it should be included in all versions of the program.
|
||||
|
||||
main.go runs the web server. It includes the "!appengine" build constraint,
|
||||
as it must only included when building the stand-alone binary.
|
||||
|
||||
// +build !appengine
|
||||
|
||||
package main
|
||||
|
||||
import "net/http"
|
||||
|
||||
func main() {
|
||||
http.ListenAndServe("localhost:8080", nil)
|
||||
}
|
||||
|
||||
To see a more complex hybrid app, take a look at the [present tool](https://godoc.org/golang.org/x/tools/present).
|
||||
|
||||
## Conclusions
|
||||
|
||||
We hope these changes will make it easier to work on apps with external dependencies,
|
||||
and to maintain code bases that contain both stand-alone programs and App Engine apps.
|
|
@ -1,35 +0,0 @@
|
|||
# Writing scalable App Engine applications
|
||||
1 Nov 2011
|
||||
Tags: appengine, optimization
|
||||
Summary: How to build scalable web applications using Go with Google App Engine.
|
||||
OldURL: /writing-scalable-app-engine
|
||||
|
||||
David Symonds
|
||||
|
||||
##
|
||||
|
||||
Back in May, we [announced](https://blog.golang.org/2011/05/go-and-google-app-engine.html)
|
||||
the Go runtime for App Engine.
|
||||
Since then, we've opened it up for everyone to use,
|
||||
added many new APIs, and improved performance.
|
||||
We have been thrilled by all the interesting ways that people are using Go on App Engine.
|
||||
One of the key benefits of the Go runtime,
|
||||
apart from working in a fantastic language,
|
||||
is that it has high performance.
|
||||
Go applications compile to native code, with no interpreter or virtual machine
|
||||
getting between your program and the machine.
|
||||
|
||||
Making your web application fast is important because it is well known that
|
||||
a web site's latency has a measurable impact on user happiness,
|
||||
and [Google web search uses it as a ranking factor](https://googlewebmastercentral.blogspot.com/2010/04/using-site-speed-in-web-search-ranking.html).
|
||||
Also announced in May was that App Engine would be [leaving its Preview status](http://googleappengine.blogspot.com/2011/05/year-ahead-for-google-app-engine.html)
|
||||
and transitioning to a [new pricing model](https://www.google.com/enterprise/cloud/appengine/pricing.html),
|
||||
providing another reason to write efficient App Engine applications.
|
||||
|
||||
To make it easier for Go developers using App Engine to write highly efficient,
|
||||
scalable applications, we recently updated some existing App Engine articles
|
||||
to include snippets of Go source code and to link to relevant Go documentation.
|
||||
|
||||
- [Best practices for writing scalable applications](http://code.google.com/appengine/articles/scaling/overview.html)
|
||||
|
||||
- [Managing Your App's Resource Usage](http://code.google.com/appengine/articles/managing-resources.html)
|
|
@ -1,77 +0,0 @@
|
|||
# Go and Google App Engine
|
||||
10 May 2011
|
||||
Tags: appengine, release
|
||||
Summary: Announcing support for Go in Google App Engine.
|
||||
OldURL: /go-and-google-app-engine
|
||||
|
||||
David Symonds
|
||||
|
||||
Nigel Tao
|
||||
|
||||
Andrew Gerrand
|
||||
|
||||
##
|
||||
|
||||
Google’s App Engine provides a reliable,
|
||||
scalable, easy way to build and deploy applications for the web.
|
||||
Over a hundred thousand apps are hosted at appspot.com and custom domains
|
||||
using the App Engine infrastructure.
|
||||
Originally written for Python apps, in 2009 the system added a Java runtime.
|
||||
And today, at Google I/O, we’re thrilled to announce that Go will be next.
|
||||
It’s marked as an experimental App Engine feature for now,
|
||||
because it’s early days, but both the App Engine and Go teams are very
|
||||
excited about this milestone.
|
||||
|
||||
By early days, we mean that it’s still rolling out.
|
||||
As of today, the App Engine SDK for Go is [available for download](http://code.google.com/p/googleappengine/downloads/list),
|
||||
and we will soon enable deployment of Go apps into the App Engine hosting infrastructure.
|
||||
Today, through the SDK, you’ll be able to write web apps,
|
||||
learn about the APIs (and the language, if it’s new to you),
|
||||
and run your web app locally.
|
||||
Once full deployment is enabled, it’ll be easy to push your app to Google’s cloud.
|
||||
|
||||
One of the cool but less obvious things about this news is that it provides
|
||||
a very easy way to play with Go.
|
||||
You don’t even need to have Go installed beforehand because the SDK is
|
||||
fully self-contained.
|
||||
Just download the SDK, unzip it, and start coding.
|
||||
Moreover, the SDK’s “dev app server” means you don’t even need to
|
||||
run the compiler yourself;
|
||||
everything is delightfully automatic.
|
||||
|
||||
What you’ll find in the SDK is many of the standard App Engine APIs,
|
||||
custom designed in good Go style, including Datastore,
|
||||
Blobstore, URL Fetch, Mail, Users, and so on.
|
||||
More APIs will be added as the environment develops.
|
||||
The runtime provides the full Go language and almost all the standard libraries,
|
||||
except for a few things that don’t make sense in the App Engine environment.
|
||||
For instance, there is no `unsafe` package and the `syscall` package is trimmed.
|
||||
(The implementation uses an expanded version of the setup in the [Go Playground](https://golang.org/doc/play/)
|
||||
on [golang.org](https://golang.org/).)
|
||||
|
||||
Also, although goroutines and channels are present,
|
||||
when a Go app runs on App Engine only one thread is run in a given instance.
|
||||
That is, all goroutines run in a single operating system thread,
|
||||
so there is no CPU parallelism available for a given client request.
|
||||
We expect this restriction will be lifted at some point.
|
||||
|
||||
Despite these minor restrictions, it’s the real language:
|
||||
Code is deployed in source form and compiled in the cloud using the 64-bit x86 compiler (6g),
|
||||
making it the first true compiled language that runs on App Engine.
|
||||
Go on App Engine makes it possible to deploy efficient,
|
||||
CPU-intensive web applications.
|
||||
|
||||
If you want to know more, read the [documentation](http://code.google.com/appengine/docs/go/)
|
||||
(start with “[Getting Started](http://code.google.com/appengine/docs/go/gettingstarted/)”).
|
||||
The libraries and SDK are open source, hosted at [http://code.google.com/p/appengine-go/](http://code.google.com/p/appengine-go/).
|
||||
We’ve created a new [google-appengine-go](http://groups.google.com/group/google-appengine-go) mailing list;
|
||||
feel free to contact us there with App Engine-specific questions.
|
||||
The [issue tracker for App Engine](http://code.google.com/p/googleappengine/issues/list)
|
||||
is the place for reporting issues related to the new Go SDK.
|
||||
|
||||
The Go App Engine SDK is [available](http://code.google.com/p/googleappengine/downloads/list)
|
||||
for Linux and Mac OS X (10.5 or greater);
|
||||
we hope a Windows version will also be available soon.
|
||||
|
||||
We’d like to offer our thanks for all the help and enthusiasm we received
|
||||
from Google’s App Engine team in making this happen.
|
|
@ -1,23 +0,0 @@
|
|||
// This server can run on App Engine.
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
port := os.Getenv("PORT")
|
||||
if port == "" {
|
||||
port = "8080"
|
||||
}
|
||||
http.HandleFunc("/", hello)
|
||||
|
||||
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), nil))
|
||||
}
|
||||
|
||||
func hello(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte("Hello, 世界"))
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
# Go Wins 2010 Bossie Award
|
||||
6 Sep 2010
|
||||
Summary: Go wins a 2010 Bossie Award for “best open source application development software.”
|
||||
OldURL: /go-wins-2010-bossie-award
|
||||
|
||||
Andrew Gerrand
|
||||
|
||||
##
|
||||
|
||||
The Go project has been awarded a [Bossie Award](http://www.infoworld.com/d/open-source/bossie-awards-2010-the-best-open-source-application-development-software-140¤t=2&last=1)
|
||||
for "best open source application development software." The [Bossie Awards](http://www.infoworld.com/d/open-source/bossie-awards-2010-the-best-open-source-software-the-year-115)
|
||||
have been given each year since 2007 by [InfoWorld](http://infoworld.com/)
|
||||
to recognize the best Open Source projects.
|
||||
Their citation reads:
|
||||
|
||||
Google's Go language tries to restore simplicity to programming.
|
||||
It does away with numerous constructs that have crept into all OO languages
|
||||
by re-imagining how to simplify and improve the conversation between a developer and the code.
|
||||
Go provides garbage collection, type safety,
|
||||
memory safety, and built-in support for concurrency and for Unicode characters.
|
||||
In addition, it compiles (fast!) to binaries for multiple platforms.
|
||||
Go is still in development (new features are being added) and it has limitations,
|
||||
notably poor support for Windows.
|
||||
But it shows a new, exciting direction in programming languages.
|
||||
|
||||
The Go team are pleased to accept this award.
|
||||
It reflects not only our hard work, but also the efforts of the growing
|
||||
community of Go developers to whom we must extend our sincere thanks.
|
|
@ -1,151 +0,0 @@
|
|||
# C? Go? Cgo!
|
||||
17 Mar 2011
|
||||
Tags: cgo, technical
|
||||
Summary: How to use cgo to let Go packages call C code.
|
||||
OldURL: /c-go-cgo
|
||||
|
||||
Andrew Gerrand
|
||||
|
||||
## Introduction
|
||||
|
||||
Cgo lets Go packages call C code. Given a Go source file written with some special features,
|
||||
cgo outputs Go and C files that can be combined into a single Go package.
|
||||
|
||||
To lead with an example, here's a Go package that provides two functions -
|
||||
`Random` and `Seed` - that wrap C's `random` and `srandom` functions.
|
||||
|
||||
package rand
|
||||
|
||||
/*
|
||||
#include <stdlib.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
func Random() int {
|
||||
return int(C.random())
|
||||
}
|
||||
|
||||
func Seed(i int) {
|
||||
C.srandom(C.uint(i))
|
||||
}
|
||||
|
||||
Let's look at what's happening here, starting with the import statement.
|
||||
|
||||
The `rand` package imports `"C"`, but you'll find there's no such package
|
||||
in the standard Go library.
|
||||
That's because `C` is a "pseudo-package",
|
||||
a special name interpreted by cgo as a reference to C's name space.
|
||||
|
||||
The `rand` package contains four references to the `C` package:
|
||||
the calls to `C.random` and `C.srandom`, the conversion `C.uint(i)`,
|
||||
and the `import` statement.
|
||||
|
||||
The `Random` function calls the standard C library's `random` function and returns the result.
|
||||
In C, `random` returns a value of the C type `long`,
|
||||
which cgo represents as the type `C.long`.
|
||||
It must be converted to a Go type before it can be used by Go code outside this package,
|
||||
using an ordinary Go type conversion:
|
||||
|
||||
func Random() int {
|
||||
return int(C.random())
|
||||
}
|
||||
|
||||
Here's an equivalent function that uses a temporary variable to illustrate the type conversion more explicitly:
|
||||
|
||||
func Random() int {
|
||||
var r C.long = C.random()
|
||||
return int(r)
|
||||
}
|
||||
|
||||
The `Seed` function does the reverse, in a way.
|
||||
It takes a regular Go `int`, converts it to the C `unsigned int` type,
|
||||
and passes it to the C function `srandom`.
|
||||
|
||||
func Seed(i int) {
|
||||
C.srandom(C.uint(i))
|
||||
}
|
||||
|
||||
Note that cgo knows the `unsigned int` type as `C.uint`;
|
||||
see the [cgo documentation](https://golang.org/cmd/cgo) for a complete
|
||||
list of these numeric type names.
|
||||
|
||||
The one detail of this example we haven't examined yet is the comment above the `import` statement.
|
||||
|
||||
/*
|
||||
#include <stdlib.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
Cgo recognizes this comment. Any lines starting with `#cgo` followed by
|
||||
a space character are removed;
|
||||
these become directives for cgo.
|
||||
The remaining lines are used as a header when compiling the C parts of the package.
|
||||
In this case those lines are just a single `#include` statement,
|
||||
but they can be almost any C code.
|
||||
The `#cgo` directives are used to provide flags for the compiler and linker
|
||||
when building the C parts of the package.
|
||||
|
||||
There is a limitation: if your program uses any `//export` directives,
|
||||
then the C code in the comment may only include declarations (`extern int f();`),
|
||||
not definitions (`int f() { return 1; }`).
|
||||
You can use `//export` directives to make Go functions accessible to C code.
|
||||
|
||||
The `#cgo` and `//export` directives are documented in the [cgo documentation](https://golang.org/cmd/cgo/).
|
||||
|
||||
## Strings and things
|
||||
|
||||
Unlike Go, C doesn't have an explicit string type. Strings in C are represented by a zero-terminated array of chars.
|
||||
|
||||
Conversion between Go and C strings is done with the `C.CString`,
|
||||
`C.GoString`, and `C.GoStringN` functions.
|
||||
These conversions make a copy of the string data.
|
||||
|
||||
This next example implements a `Print` function that writes a string to
|
||||
standard output using C's `fputs` function from the `stdio` library:
|
||||
|
||||
package print
|
||||
|
||||
// #include <stdio.h>
|
||||
// #include <stdlib.h>
|
||||
import "C"
|
||||
import "unsafe"
|
||||
|
||||
func Print(s string) {
|
||||
cs := C.CString(s)
|
||||
C.fputs(cs, (*C.FILE)(C.stdout))
|
||||
C.free(unsafe.Pointer(cs))
|
||||
}
|
||||
|
||||
Memory allocations made by C code are not known to Go's memory manager.
|
||||
When you create a C string with `C.CString` (or any C memory allocation)
|
||||
you must remember to free the memory when you're done with it by calling `C.free`.
|
||||
|
||||
The call to `C.CString` returns a pointer to the start of the char array,
|
||||
so before the function exits we convert it to an [`unsafe.Pointer`](https://golang.org/pkg/unsafe/#Pointer)
|
||||
and release the memory allocation with `C.free`.
|
||||
A common idiom in cgo programs is to [`defer`](https://golang.org/doc/articles/defer_panic_recover.html)
|
||||
the free immediately after allocating (especially when the code that follows
|
||||
is more complex than a single function call),
|
||||
as in this rewrite of `Print`:
|
||||
|
||||
func Print(s string) {
|
||||
cs := C.CString(s)
|
||||
defer C.free(unsafe.Pointer(cs))
|
||||
C.fputs(cs, (*C.FILE)(C.stdout))
|
||||
}
|
||||
|
||||
## Building cgo packages
|
||||
|
||||
To build cgo packages, just use [`go build`](https://golang.org/cmd/go/#hdr-Compile_packages_and_dependencies)
|
||||
or [`go install`](https://golang.org/cmd/go/#hdr-Compile_and_install_packages_and_dependencies) as usual.
|
||||
The go tool recognizes the special `"C"` import and automatically uses cgo for those files.
|
||||
|
||||
## More cgo resources
|
||||
|
||||
The [cgo command](https://golang.org/cmd/cgo/) documentation has more
|
||||
detail about the C pseudo-package and the build process.
|
||||
The [cgo examples](https://golang.org/misc/cgo/) in the Go tree demonstrate
|
||||
more advanced concepts.
|
||||
|
||||
Finally, if you're curious as to how all this works internally,
|
||||
take a look at the introductory comment of the runtime package's [cgocall.go](https://golang.org/src/runtime/cgocall.go).
|
|
@ -1,107 +0,0 @@
|
|||
# Share Memory By Communicating
|
||||
13 Jul 2010
|
||||
Tags: concurrency, technical
|
||||
Summary: A preview of the new Go codelab, Share Memory by Communicating.
|
||||
OldURL: /share-memory-by-communicating
|
||||
|
||||
Andrew Gerrand
|
||||
|
||||
##
|
||||
|
||||
Traditional threading models (commonly used when writing Java,
|
||||
C++, and Python programs, for example) require the programmer to communicate
|
||||
between threads using shared memory.
|
||||
Typically, shared data structures are protected by locks,
|
||||
and threads will contend over those locks to access the data.
|
||||
In some cases, this is made easier by the use of thread-safe data structures
|
||||
such as Python's Queue.
|
||||
|
||||
Go's concurrency primitives - goroutines and channels - provide an elegant
|
||||
and distinct means of structuring concurrent software.
|
||||
(These concepts have an [interesting history](https://swtch.com/~rsc/thread/) that begins with C.
|
||||
A. R. Hoare's [Communicating Sequential Processes](http://www.usingcsp.com/).)
|
||||
Instead of explicitly using locks to mediate access to shared data,
|
||||
Go encourages the use of channels to pass references to data between goroutines.
|
||||
This approach ensures that only one goroutine has access to the data at a given time.
|
||||
The concept is summarized in the document [Effective Go](https://golang.org/doc/effective_go.html)
|
||||
(a must-read for any Go programmer):
|
||||
|
||||
_Do not communicate by sharing memory; instead, share memory by communicating._
|
||||
|
||||
Consider a program that polls a list of URLs.
|
||||
In a traditional threading environment, one might structure its data like so:
|
||||
|
||||
type Resource struct {
|
||||
url string
|
||||
polling bool
|
||||
lastPolled int64
|
||||
}
|
||||
|
||||
type Resources struct {
|
||||
data []*Resource
|
||||
lock *sync.Mutex
|
||||
}
|
||||
|
||||
And then a Poller function (many of which would run in separate threads) might look something like this:
|
||||
|
||||
func Poller(res *Resources) {
|
||||
for {
|
||||
// get the least recently-polled Resource
|
||||
// and mark it as being polled
|
||||
res.lock.Lock()
|
||||
var r *Resource
|
||||
for _, v := range res.data {
|
||||
if v.polling {
|
||||
continue
|
||||
}
|
||||
if r == nil || v.lastPolled < r.lastPolled {
|
||||
r = v
|
||||
}
|
||||
}
|
||||
if r != nil {
|
||||
r.polling = true
|
||||
}
|
||||
res.lock.Unlock()
|
||||
if r == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// poll the URL
|
||||
|
||||
// update the Resource's polling and lastPolled
|
||||
res.lock.Lock()
|
||||
r.polling = false
|
||||
r.lastPolled = time.Nanoseconds()
|
||||
res.lock.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
This function is about a page long, and requires more detail to make it complete.
|
||||
It doesn't even include the URL polling logic (which,
|
||||
itself, would only be a few lines), nor will it gracefully handle exhausting
|
||||
the pool of Resources.
|
||||
|
||||
Let's take a look at the same functionality implemented using Go idiom.
|
||||
In this example, Poller is a function that receives Resources to be polled
|
||||
from an input channel,
|
||||
and sends them to an output channel when they're done.
|
||||
|
||||
type Resource string
|
||||
|
||||
func Poller(in, out chan *Resource) {
|
||||
for r := range in {
|
||||
// poll the URL
|
||||
|
||||
// send the processed Resource to out
|
||||
out <- r
|
||||
}
|
||||
}
|
||||
|
||||
The delicate logic from the previous example is conspicuously absent,
|
||||
and our Resource data structure no longer contains bookkeeping data.
|
||||
In fact, all that's left are the important parts.
|
||||
This should give you an inkling as to the power of these simple language features.
|
||||
|
||||
There are many omissions from the above code snippets.
|
||||
For a walkthrough of a complete, idiomatic Go program that uses these ideas,
|
||||
see the Codewalk [_Share Memory By Communicating_](https://golang.org/doc/codewalk/sharemem/).
|
|
@ -1,84 +0,0 @@
|
|||
# Go Concurrency Patterns: Timing out, moving on
|
||||
23 Sep 2010
|
||||
Tags: concurrency, technical
|
||||
Summary: How to implement timeouts using Go's concurrency support.
|
||||
OldURL: /go-concurrency-patterns-timing-out-and
|
||||
|
||||
Andrew Gerrand
|
||||
|
||||
##
|
||||
|
||||
Concurrent programming has its own idioms.
|
||||
A good example is timeouts. Although Go's channels do not support them directly,
|
||||
they are easy to implement.
|
||||
Say we want to receive from the channel `ch`,
|
||||
but want to wait at most one second for the value to arrive.
|
||||
We would start by creating a signalling channel and launching a goroutine
|
||||
that sleeps before sending on the channel:
|
||||
|
||||
timeout := make(chan bool, 1)
|
||||
go func() {
|
||||
time.Sleep(1 * time.Second)
|
||||
timeout <- true
|
||||
}()
|
||||
|
||||
We can then use a `select` statement to receive from either `ch` or `timeout`.
|
||||
If nothing arrives on `ch` after one second,
|
||||
the timeout case is selected and the attempt to read from ch is abandoned.
|
||||
|
||||
select {
|
||||
case <-ch:
|
||||
// a read from ch has occurred
|
||||
case <-timeout:
|
||||
// the read from ch has timed out
|
||||
}
|
||||
|
||||
The `timeout` channel is buffered with space for 1 value,
|
||||
allowing the timeout goroutine to send to the channel and then exit.
|
||||
The goroutine doesn't know (or care) whether the value is received.
|
||||
This means the goroutine won't hang around forever if the `ch` receive happens
|
||||
before the timeout is reached.
|
||||
The `timeout` channel will eventually be deallocated by the garbage collector.
|
||||
|
||||
(In this example we used `time.Sleep` to demonstrate the mechanics of goroutines and channels.
|
||||
In real programs you should use ` [time.After](https://golang.org/pkg/time/#After)`,
|
||||
a function that returns a channel and sends on that channel after the specified duration.)
|
||||
|
||||
Let's look at another variation of this pattern.
|
||||
In this example we have a program that reads from multiple replicated databases simultaneously.
|
||||
The program needs only one of the answers,
|
||||
and it should accept the answer that arrives first.
|
||||
|
||||
The function `Query` takes a slice of database connections and a `query` string.
|
||||
It queries each of the databases in parallel and returns the first response it receives:
|
||||
|
||||
func Query(conns []Conn, query string) Result {
|
||||
ch := make(chan Result)
|
||||
for _, conn := range conns {
|
||||
go func(c Conn) {
|
||||
select {
|
||||
case ch <- c.DoQuery(query):
|
||||
default:
|
||||
}
|
||||
}(conn)
|
||||
}
|
||||
return <-ch
|
||||
}
|
||||
|
||||
In this example, the closure does a non-blocking send,
|
||||
which it achieves by using the send operation in `select` statement with a `default` case.
|
||||
If the send cannot go through immediately the default case will be selected.
|
||||
Making the send non-blocking guarantees that none of the goroutines launched
|
||||
in the loop will hang around.
|
||||
However, if the result arrives before the main function has made it to the receive,
|
||||
the send could fail since no one is ready.
|
||||
|
||||
This problem is a textbook example of what is known as a [race condition](https://en.wikipedia.org/wiki/Race_condition),
|
||||
but the fix is trivial.
|
||||
We just make sure to buffer the channel `ch` (by adding the buffer length
|
||||
as the second argument to [make](https://golang.org/pkg/builtin/#make)),
|
||||
guaranteeing that the first send has a place to put the value.
|
||||
This ensures the send will always succeed,
|
||||
and the first value to arrive will be retrieved regardless of the order of execution.
|
||||
|
||||
These two examples demonstrate the simplicity with which Go can express complex interactions between goroutines.
|
|
@ -1,96 +0,0 @@
|
|||
# Updating the Go Code of Conduct
|
||||
23 May 2018
|
||||
Tags: conduct
|
||||
Summary: Revising the Go Code of Conduct.
|
||||
|
||||
Steve Francia
|
||||
|
||||
##
|
||||
|
||||
In November 2015, we introduced the Go Code of Conduct.
|
||||
It was developed in a collaboration between
|
||||
the Go team members at Google and the Go community.
|
||||
I was fortunate to be one of the community members
|
||||
invited to participate in both drafting and then enforcing
|
||||
the Go Code of Conduct.
|
||||
Since then, we have learned two lessons about
|
||||
limitations in our code of conduct that restricted us from
|
||||
being able to cultivate the safe culture
|
||||
essential to Go’s success.
|
||||
|
||||
The first lesson we learned is that toxic behaviors by
|
||||
project participants in non-project spaces can have a
|
||||
negative impact on the project affecting the security and safety of
|
||||
community members. There were a few reported
|
||||
incidents where actions took place outside of project spaces
|
||||
but the impact was felt inside our community. The specific
|
||||
language in our code of conduct restricted our ability to
|
||||
respond only to actions happening “in the official
|
||||
forums operated by the Go project”. We needed a way
|
||||
to protect our community members wherever they are.
|
||||
|
||||
The second lesson we learned is that the demands required
|
||||
to enforce the code
|
||||
of conduct place too heavy of a burden on volunteers.
|
||||
The initial version of the code of conduct presented the
|
||||
working group as disciplinarians. It was soon clear
|
||||
that this was too much, so in early 2017 [we changed the group’s role](https://golang.org/cl/37014)
|
||||
to that of advisors and mediators.
|
||||
Still, working group community members
|
||||
reported feeling overwhelmed, untrained, and vulnerable.
|
||||
This well-intentioned shift left us without an enforcement mechanism
|
||||
without solving the issue with overburdened volunteers.
|
||||
|
||||
In mid-2017, I represented the Go project in a meeting with
|
||||
Google’s Open Source Programs Office and Open Source Strategy Team
|
||||
to address the shortcomings in our respective
|
||||
codes of conduct, particularly in their enforcement.
|
||||
It quickly became clear that our problems had a lot in common,
|
||||
and that working together on a single code of conduct for all
|
||||
of Google’s open source projects made sense.
|
||||
We started with the text from the
|
||||
Contributor Covenant Code of Conduct v1.4
|
||||
and then made changes, influenced by
|
||||
our experiences in Go community and our collective experiences in open source.
|
||||
This resulted in the Google [code of conduct template](https://opensource.google.com/docs/releasing/template/CODE_OF_CONDUCT/).
|
||||
|
||||
Today the Go project is adopting this new code of conduct,
|
||||
and we’ve updated [golang.org/conduct](https://golang.org/conduct).
|
||||
This revised code of conduct retains much of the intent, structure and
|
||||
language of the original Go code of conduct while making two critical
|
||||
changes that address the shortcomings identified above.
|
||||
|
||||
First, [the new code of conduct makes clear](https://golang.org/conduct/#scope) that people who
|
||||
participate in any kind of harassment or inappropriate behavior,
|
||||
even outside our project spaces, are not welcome in our project spaces.
|
||||
This means that the Code of Conduct applies outside
|
||||
the project spaces when there is a reasonable belief that
|
||||
an individual’s behavior may have a negative
|
||||
impact on the project or its community.
|
||||
|
||||
Second, in the place of the working group,
|
||||
[the new code of conduct introduces a single Project Steward](https://golang.org/conduct/#reporting)
|
||||
who will have explicit training and support for this role.
|
||||
The Project Steward will receive reported violations
|
||||
and then work with a committee,
|
||||
consisting of representatives from the Open Source Programs Office
|
||||
and the Google Open Source Strategy team,
|
||||
to find a resolution.
|
||||
|
||||
Our first Project Steward will be [Cassandra Salisbury](https://twitter.com/cassandraoid).
|
||||
She is well known to the Go community as a member of Go Bridge,
|
||||
an organizer of many Go meetups and conferences,
|
||||
and as a lead of the Go community outreach working group.
|
||||
Cassandra now works on the Go team at Google
|
||||
with a focus on advocating for and supporting the Go community.
|
||||
|
||||
We are grateful to everyone who served on the original Code of
|
||||
Conduct Working Group. Your efforts were essential in creating an
|
||||
inclusive and safe community.
|
||||
|
||||
We believe the code of conduct has contributed to the
|
||||
Go project becoming more welcoming now than it was in 2015,
|
||||
and we should all be proud of that.
|
||||
|
||||
We hope that the new code of conduct will help protect our community
|
||||
members even more effectively.
|
|
@ -1,515 +0,0 @@
|
|||
# Constants
|
||||
25 Aug 2014
|
||||
Tags: constants
|
||||
Summary: An introduction to constants in Go.
|
||||
|
||||
Rob Pike
|
||||
|
||||
## Introduction
|
||||
|
||||
Go is a statically typed language that does not permit operations that mix numeric types.
|
||||
You can't add a `float64` to an `int`, or even an `int32` to an `int`.
|
||||
Yet it is legal to write `1e6*time.Second` or `math.Exp(1)` or even `1<<('\t'+2.0)`.
|
||||
In Go, constants, unlike variables, behave pretty much like regular numbers.
|
||||
This post explains why that is and what it means.
|
||||
|
||||
## Background: C
|
||||
|
||||
In the early days of thinking about Go, we talked about a number of problems
|
||||
caused by the way C and its descendants let you mix and match numeric types.
|
||||
Many mysterious bugs, crashes, and portability problems are caused by expressions
|
||||
that combine integers of different sizes and "signedness".
|
||||
Although to a seasoned C programmer the result of a calculation like
|
||||
|
||||
unsigned int u = 1e9;
|
||||
long signed int i = -1;
|
||||
... i + u ...
|
||||
|
||||
may be familiar, it isn't _a priori_ obvious.
|
||||
How big is the result?
|
||||
What is its value?
|
||||
Is it signed or unsigned?
|
||||
|
||||
Nasty bugs lurk here.
|
||||
|
||||
C has a set of rules called "the usual arithmetic conversions" and it is
|
||||
an indicator of their subtlety that they have changed over the years (introducing
|
||||
yet more bugs, retroactively).
|
||||
|
||||
When designing Go, we decided to avoid this minefield by mandating that there is _no_ mixing of numeric types.
|
||||
If you want to add `i` and `u`, you must be explicit about what you want the result to be.
|
||||
Given
|
||||
|
||||
var u uint
|
||||
var i int
|
||||
|
||||
you can write either `uint(i)+u` or `i+int(u)`,
|
||||
with both the meaning and type of the addition clearly expressed,
|
||||
but unlike in C you cannot write `i+u`.
|
||||
You can't even mix `int` and `int32`, even when `int` is a 32-bit type.
|
||||
|
||||
This strictness eliminates a common cause of bugs and other failures.
|
||||
It is a vital property of Go.
|
||||
But it has a cost: it sometimes requires programmers to decorate their code
|
||||
with clumsy numeric conversions to express their meaning clearly.
|
||||
|
||||
And what about constants?
|
||||
Given the declarations above, what would make it legal to write `i` `=` `0` or `u` `=` `0`?
|
||||
What is the _type_ of `0`?
|
||||
It would be unreasonable to require constants to have type conversions in simple contexts such as `i` `=` `int(0)`.
|
||||
|
||||
We soon realized the answer lay in making numeric constants work differently
|
||||
from how they behave in other C-like languages.
|
||||
After much thinking and experimentation, we came up with a design that we
|
||||
believe feels right almost always,
|
||||
freeing the programmer from converting constants all the time yet being
|
||||
able to write things like `math.Sqrt(2)` without being chided by the compiler.
|
||||
|
||||
In short, constants in Go just work, most of the time anyway.
|
||||
Let's see how that happens.
|
||||
|
||||
## Terminology
|
||||
|
||||
First, a quick definition.
|
||||
In Go, `const` is a keyword introducing a name for a scalar value such as `2` or `3.14159` or `"scrumptious"`.
|
||||
Such values, named or otherwise, are called _constants_ in Go.
|
||||
Constants can also be created by expressions built from constants,
|
||||
such as `2+3` or `2+3i` or `math.Pi/2` or `("go"+"pher")`.
|
||||
|
||||
Some languages don't have constants, and others have a more general definition
|
||||
of constant or application of the word `const`.
|
||||
In C and C++, for instance, `const` is a type qualifier that can codify
|
||||
more intricate properties of more intricate values.
|
||||
|
||||
But in Go, a constant is just a simple, unchanging value, and from here on we're talking only about Go.
|
||||
|
||||
## String constants
|
||||
|
||||
There are many kinds of numeric constants—integers,
|
||||
floats, runes, signed, unsigned, imaginary,
|
||||
complex—so let's start with a simpler form of constant: strings.
|
||||
String constants are easy to understand and provide a smaller space in which
|
||||
to explore the type issues of constants in Go.
|
||||
|
||||
A string constant encloses some text between double quotes.
|
||||
(Go also has raw string literals, enclosed by backquotes <code>``</code>,
|
||||
but for the purpose of this discussion they have all the same properties.)
|
||||
Here is a string constant:
|
||||
|
||||
"Hello, 世界"
|
||||
|
||||
(For much more detail about the representation and interpretation of strings,
|
||||
see [this blog post](https://blog.golang.org/strings).)
|
||||
|
||||
What type does this string constant have?
|
||||
The obvious answer is `string`, but that is _wrong_.
|
||||
|
||||
This is an _untyped string constant_, which is to say it is a constant textual
|
||||
value that does not yet have a fixed type.
|
||||
Yes, it's a string, but it's not a Go value of type `string`.
|
||||
It remains an untyped string constant even when given a name:
|
||||
|
||||
const hello = "Hello, 世界"
|
||||
|
||||
After this declaration, `hello` is also an untyped string constant.
|
||||
An untyped constant is just a value, one not yet given a defined type that
|
||||
would force it to obey the strict rules that prevent combining differently typed values.
|
||||
|
||||
It is this notion of an _untyped_ constant that makes it possible for us to use constants in Go with great freedom.
|
||||
|
||||
So what, then, is a _typed_ string constant?
|
||||
It's one that's been given a type, like this:
|
||||
|
||||
const typedHello string = "Hello, 世界"
|
||||
|
||||
Notice that the declaration of `typedHello` has an explicit `string` type before the equals sign.
|
||||
This means that `typedHello` has Go type `string`, and cannot be assigned to a Go variable of a different type.
|
||||
That is to say, this code works:
|
||||
|
||||
.play -edit constants/string1.go /START/,/STOP/
|
||||
|
||||
but this does not:
|
||||
|
||||
.play -edit constants/string2.go /START/,/STOP/
|
||||
|
||||
The variable `m` has type `MyString` and cannot be assigned a value of a different type.
|
||||
It can only be assigned values of type `MyString`, like this:
|
||||
|
||||
.play -edit constants/string3.go /START/,/STOP/
|
||||
|
||||
or by forcing the issue with a conversion, like this:
|
||||
|
||||
.play -edit constants/string4.go /START/,/STOP/
|
||||
|
||||
Returning to our _untyped_ string constant,
|
||||
it has the helpful property that, since it has no type,
|
||||
assigning it to a typed variable does not cause a type error.
|
||||
That is, we can write
|
||||
|
||||
m = "Hello, 世界"
|
||||
|
||||
or
|
||||
|
||||
m = hello
|
||||
|
||||
because, unlike the typed constants `typedHello` and `myStringHello`,
|
||||
the untyped constants `"Hello, 世界"` and `hello` _have no type_.
|
||||
Assigning them to a variable of any type compatible with strings works without error.
|
||||
|
||||
These untyped string constants are strings,
|
||||
of course, so they can only be used where a string is allowed,
|
||||
but they do not have _type_ `string`.
|
||||
|
||||
## Default type
|
||||
|
||||
As a Go programmer, you have certainly seen many declarations like
|
||||
|
||||
str := "Hello, 世界"
|
||||
|
||||
and by now you might be asking, "if the constant is untyped, how does `str` get a type in this variable declaration?"
|
||||
The answer is that an untyped constant has a default type,
|
||||
an implicit type that it transfers to a value if a type is needed where none is provided.
|
||||
For untyped string constants, that default type is obviously `string`, so
|
||||
|
||||
str := "Hello, 世界"
|
||||
|
||||
or
|
||||
|
||||
var str = "Hello, 世界"
|
||||
|
||||
means exactly the same as
|
||||
|
||||
var str string = "Hello, 世界"
|
||||
|
||||
One way to think about untyped constants is that they live in a kind of
|
||||
ideal space of values,
|
||||
a space less restrictive than Go's full type system.
|
||||
But to do anything with them, we need to assign them to variables,
|
||||
and when that happens the _variable_ (not the constant itself) needs a type,
|
||||
and the constant can tell the variable what type it should have.
|
||||
In this example, `str` becomes a value of type `string` because the untyped
|
||||
string constant gives the declaration its default type, `string`.
|
||||
|
||||
In such a declaration, a variable is declared with a type and initial value.
|
||||
Sometimes when we use a constant, however, the destination of the value is not so clear.
|
||||
For instance consider this statement:
|
||||
|
||||
.play -edit constants/default1.go /START/,/STOP/
|
||||
|
||||
The signature of `fmt.Printf` is
|
||||
|
||||
func Printf(format string, a ...interface{}) (n int, err error)
|
||||
|
||||
which is to say its arguments (after the format string) are interface values.
|
||||
What happens when `fmt.Printf` is called with an untyped constant is that an interface value is created
|
||||
to pass as an argument, and the concrete type stored for that argument is the default type of the constant.
|
||||
This process is analogous to what we saw earlier when declaring an initialized value using an untyped string constant.
|
||||
|
||||
You can see the result in this example, which uses the format `%v` to print
|
||||
the value and `%T` to print the type of the value being passed to `fmt.Printf`:
|
||||
|
||||
.play -edit constants/default2.go /START/,/STOP/
|
||||
|
||||
If the constant has a type, that goes into the interface, as this example shows:
|
||||
|
||||
.play -edit constants/default3.go /START/,/STOP/
|
||||
|
||||
(For more information about how interface values work,
|
||||
see the first sections of [this blog post](https://blog.golang.org/laws-of-reflection).)
|
||||
|
||||
In summary, a typed constant obeys all the rules of typed values in Go.
|
||||
On the other hand, an untyped constant does not carry a Go type in the same
|
||||
way and can be mixed and matched more freely.
|
||||
It does, however, have a default type that is exposed when, and only when, no other type information is available.
|
||||
|
||||
## Default type determined by syntax
|
||||
|
||||
The default type of an untyped constant is determined by its syntax.
|
||||
For string constants, the only possible implicit type is `string`.
|
||||
For [numeric constants](https://golang.org/ref/spec#Numeric_types), the implicit type has more variety.
|
||||
Integer constants default to `int`, floating-point constants `float64`,
|
||||
rune constants to `rune` (an alias for `int32`),
|
||||
and imaginary constants to `complex128`.
|
||||
Here's our canonical print statement used repeatedly to show the default types in action:
|
||||
|
||||
.play -edit constants/syntax.go /START/,/STOP/
|
||||
|
||||
(Exercise: Explain the result for `'x'`.)
|
||||
|
||||
## Booleans
|
||||
|
||||
Everything we said about untyped string constants can be said for untyped boolean constants.
|
||||
The values `true` and `false` are untyped boolean constants that can be assigned to any boolean variable,
|
||||
but once given a type, boolean variables cannot be mixed:
|
||||
|
||||
.play -edit constants/bool.go /START/,/STOP/
|
||||
|
||||
Run the example and see what happens, then comment out the "Bad" line and run it again.
|
||||
The pattern here follows exactly that of string constants.
|
||||
|
||||
## Floats
|
||||
|
||||
Floating-point constants are just like boolean constants in most respects.
|
||||
Our standard example works as expected in translation:
|
||||
|
||||
.play -edit constants/float1.go /START/,/STOP/
|
||||
|
||||
One wrinkle is that there are _two_ floating-point types in Go: `float32` and `float64`.
|
||||
The default type for a floating-point constant is `float64`, although an untyped floating-point
|
||||
constant can be assigned to a `float32` value just fine:
|
||||
|
||||
.play -edit constants/float2.go /START/,/STOP/
|
||||
|
||||
Floating-point values are a good place to introduce the concept of overflow, or the range of values.
|
||||
|
||||
Numeric constants live in an arbitrary-precision numeric space; they are just regular numbers.
|
||||
But when they are assigned to a variable the value must be able to fit in the destination.
|
||||
We can declare a constant with a very large value:
|
||||
|
||||
.code constants/float3.go /Huge/
|
||||
|
||||
—that's just a number, after all—but we can't assign it or even print it. This statement won't even compile:
|
||||
|
||||
.play -edit constants/float3.go /Println/
|
||||
|
||||
The error is, "constant 1.00000e+1000 overflows float64", which is true.
|
||||
But `Huge` might be useful: we can use it in expressions with other constants
|
||||
and use the value of those expressions if the result
|
||||
can be represented in the range of a `float64`.
|
||||
The statement,
|
||||
|
||||
.play -edit constants/float4.go /Println/
|
||||
|
||||
prints `10`, as one would expect.
|
||||
|
||||
In a related way, floating-point constants may have very high precision,
|
||||
so that arithmetic involving them is more accurate.
|
||||
The constants defined in the [math](https://golang.org/pkg/math) package are given with many more digits than are
|
||||
available in a `float64`. Here is the definition of `math.Pi`:
|
||||
|
||||
Pi = 3.14159265358979323846264338327950288419716939937510582097494459
|
||||
|
||||
When that value is assigned to a variable,
|
||||
some of the precision will be lost;
|
||||
the assignment will create the `float64` (or `float32`)
|
||||
value closest to the high-precision value. This snippet
|
||||
|
||||
.play -edit constants/float5.go /START/,/STOP/
|
||||
|
||||
prints `3.141592653589793`.
|
||||
|
||||
Having so many digits available means that calculations like `Pi/2` or other
|
||||
more intricate evaluations can carry more precision
|
||||
until the result is assigned, making calculations involving constants easier to write without losing precision.
|
||||
It also means that there is no occasion in which the floating-point corner cases like infinities,
|
||||
soft underflows, and `NaNs` arise in constant expressions.
|
||||
(Division by a constant zero is a compile-time error,
|
||||
and when everything is a number there's no such thing as "not a number".)
|
||||
|
||||
## Complex numbers
|
||||
|
||||
Complex constants behave a lot like floating-point constants.
|
||||
Here's a version of our now-familiar litany translated into complex numbers:
|
||||
|
||||
.play -edit constants/complex1.go /START/,/STOP/
|
||||
|
||||
The default type of a complex number is `complex128`, the larger-precision version composed of two `float64` values.
|
||||
|
||||
For clarity in our example, we wrote out the full expression `(0.0+1.0i)`,
|
||||
but this value can be shortened to `0.0+1.0i`,
|
||||
`1.0i` or even `1i`.
|
||||
|
||||
Let's play a trick.
|
||||
We know that in Go, a numeric constant is just a number.
|
||||
What if that number is a complex number with no imaginary part, that is, a real?
|
||||
Here's one:
|
||||
|
||||
.code constants/complex2.go /const Two/
|
||||
|
||||
That's an untyped complex constant.
|
||||
Even though it has no imaginary part, the _syntax_ of the expression defines it to have default type `complex128`.
|
||||
Therefore, if we use it to declare a variable, the default type will be `complex128`. The snippet
|
||||
|
||||
.play -edit constants/complex2.go /START/,/STOP/
|
||||
|
||||
prints `complex128:` `(2+0i)`.
|
||||
But numerically, `Two` can be stored in a scalar floating-point number,
|
||||
a `float64` or `float32`, with no loss of information.
|
||||
Thus we can assign `Two` to a `float64`, either in an initialization or an assignment, without problems:
|
||||
|
||||
.play -edit constants/complex3.go /START/,/STOP/
|
||||
|
||||
The output is `2` `and` `2`.
|
||||
Even though `Two` is a complex constant, it can be assigned to scalar floating-point variables.
|
||||
This ability for a constant to "cross" types like this will prove useful.
|
||||
|
||||
## Integers
|
||||
|
||||
At last we come to integers.
|
||||
They have more moving parts—[many sizes, signed or unsigned, and more](https://golang.org/ref/spec#Numeric_types)—but
|
||||
they play by the same rules.
|
||||
For the last time, here is our familiar example, using just `int` this time:
|
||||
|
||||
.play -edit constants/int1.go /START/,/STOP/
|
||||
|
||||
The same example could be built for any of the integer types, which are:
|
||||
|
||||
int int8 int16 int32 int64
|
||||
uint uint8 uint16 uint32 uint64
|
||||
uintptr
|
||||
|
||||
(plus the aliases `byte` for `uint8` and `rune` for `int32`).
|
||||
That's a lot, but the pattern in the way constants work should be familiar
|
||||
enough by now that you can see how things will play out.
|
||||
|
||||
As mentioned above, integers come in a couple of forms and each form has
|
||||
its own default type:
|
||||
`int` for simple constants like `123` or `0xFF` or `-14`
|
||||
and `rune` for quoted characters like 'a', '世' or '\r'.
|
||||
|
||||
No constant form has as its default type an unsigned integer type.
|
||||
However, the flexibility of untyped constants means we can initialize unsigned
|
||||
integer variables using simple constants as long as we are clear about the type.
|
||||
It's analogous to how we can initialize a `float64` using a complex number with zero imaginary part.
|
||||
Here are several different ways to initialize a `uint`;
|
||||
all are equivalent, but all must mention the type explicitly for the result to be unsigned.
|
||||
|
||||
var u uint = 17
|
||||
var u = uint(17)
|
||||
u := uint(17)
|
||||
|
||||
Similarly to the range issue mentioned in the section on floating-point values,
|
||||
not all integer values can fit in all integer types.
|
||||
There are two problems that might arise: the value might be too large,
|
||||
or it might be a negative value being assigned to an unsigned integer type.
|
||||
For instance, `int8` has range -128 through 127,
|
||||
so constants outside of that range can never be assigned to a variable of type `int8`:
|
||||
|
||||
.play -edit constants/int2.go /var/
|
||||
|
||||
Similarly, `uint8`, also known as `byte`,
|
||||
has range 0 through 255, so a large or negative constant cannot be assigned to a `uint8`:
|
||||
|
||||
.play -edit constants/int3.go /var/
|
||||
|
||||
This type-checking can catch mistakes like this one:
|
||||
|
||||
.play -edit constants/int4.go /START/,/STOP/
|
||||
|
||||
If the compiler complains about your use of a constant, it's likely a real bug like this.
|
||||
|
||||
## An exercise: The largest unsigned int
|
||||
|
||||
Here is an informative little exercise.
|
||||
How do we express a constant representing the largest value that fits in a `uint`?
|
||||
If we were talking about `uint32` rather than `uint`, we could write
|
||||
|
||||
const MaxUint32 = 1<<32 - 1
|
||||
|
||||
but we want `uint`, not `uint32`.
|
||||
The `int` and `uint` types have equal unspecified numbers of bits, either 32 or 64.
|
||||
Since the number of bits available depends on the architecture, we can't just write down a single value.
|
||||
|
||||
Fans of [two's-complement arithmetic](http://en.wikipedia.org/wiki/Two's_complement),
|
||||
which Go's integers are defined to use, know that the representation of `-1` has all its bits set to 1,
|
||||
so the bit pattern of `-1` is internally the same as that of the
|
||||
largest unsigned integer.
|
||||
We therefore might think we could write
|
||||
|
||||
.play -edit constants/exercise1.go /const/
|
||||
|
||||
but that is illegal because -1 cannot be represented by an unsigned variable;
|
||||
`-1` is not in the range of unsigned values.
|
||||
A conversion won't help either, for the same reason:
|
||||
|
||||
.play -edit constants/exercise2.go /const/
|
||||
|
||||
Even though at run-time a value of -1 can be converted to an unsigned integer, the rules
|
||||
for constant [conversions](https://golang.org/ref/spec#Conversions) forbid this kind of coercion at compile time.
|
||||
That is to say, this works:
|
||||
|
||||
.play -edit constants/exercise3.go /START/,/STOP/
|
||||
|
||||
but only because `v` is a variable; if we made `v` a constant,
|
||||
even an untyped constant, we'd be back in forbidden territory:
|
||||
|
||||
.play -edit constants/exercise4.go /START/,/STOP/
|
||||
|
||||
We return to our previous approach, but instead of `-1` we try `^0`,
|
||||
the bitwise negation of an arbitrary number of zero bits.
|
||||
But that fails too, for a similar reason:
|
||||
In the space of numeric values,
|
||||
`^0` represents an infinite number of ones, so we lose information if we assign that to any fixed-size integer:
|
||||
|
||||
.play -edit constants/exercise5.go /const/
|
||||
|
||||
How then do we represent the largest unsigned integer as a constant?
|
||||
|
||||
The key is to constrain the operation to the number of bits in a `uint` and avoiding
|
||||
values, such as negative numbers, that are not representable in a `uint`.
|
||||
The simplest `uint` value is the typed constant `uint(0)`.
|
||||
If `uints` have 32 or 64 bits, `uint(0)` has 32 or 64 zero bits accordingly.
|
||||
If we invert each of those bits, we'll get the correct number of one bits, which is the largest `uint` value.
|
||||
|
||||
Therefore we don't flip the bits of the untyped constant `0`, we flip the bits of the typed constant `uint(0)`.
|
||||
Here, then, is our constant:
|
||||
|
||||
.play -edit constants/exercise6.go /START/,/STOP/
|
||||
|
||||
Whatever the number of bits it takes to represent a `uint` in the current execution environment
|
||||
(on the [playground](https://blog.golang.org/playground), it's 32),
|
||||
this constant correctly represents the largest value a variable of type `uint` can hold.
|
||||
|
||||
If you understand the analysis that got us to this result,
|
||||
you understand all the important points about constants in Go.
|
||||
|
||||
## Numbers
|
||||
|
||||
The concept of untyped constants in Go means that all the numeric constants,
|
||||
whether integer, floating-point, complex,
|
||||
or even character values,
|
||||
live in a kind of unified space.
|
||||
It's when we bring them to the computational world of variables,
|
||||
assignments, and operations that the actual types matter.
|
||||
But as long as we stay in the world of numeric constants, we can mix and match values as we like.
|
||||
All these constants have numeric value 1:
|
||||
|
||||
1
|
||||
1.000
|
||||
1e3-99.0*10-9
|
||||
'\x01'
|
||||
'\u0001'
|
||||
'b' - 'a'
|
||||
1.0+3i-3.0i
|
||||
|
||||
Therefore, although they have different implicit default types,
|
||||
written as untyped constants they can be assigned to a variable of any integer type:
|
||||
|
||||
.play -edit constants/numbers1.go /START/,/STOP/
|
||||
|
||||
The output from this snippet is: `1 1 1 1 1 (1+0i) 1`.
|
||||
|
||||
You can even do nutty stuff like
|
||||
|
||||
.play -edit constants/numbers2.go /START/,/STOP/
|
||||
|
||||
which yields 145.5, which is pointless except to prove a point.
|
||||
|
||||
But the real point of these rules is flexibility.
|
||||
That flexibility means that, despite the fact that in Go it is illegal in
|
||||
the same expression to mix floating-point and integer variables,
|
||||
or even `int` and `int32` variables, it is fine to write
|
||||
|
||||
sqrt2 := math.Sqrt(2)
|
||||
|
||||
or
|
||||
|
||||
const millisecond = time.Second/1e3
|
||||
|
||||
or
|
||||
|
||||
bigBufferWithHeader := make([]byte, 512+1e6)
|
||||
|
||||
and have the results mean what you expect.
|
||||
|
||||
Because in Go, numeric constants work as you expect: like numbers.
|
|
@ -1,18 +0,0 @@
|
|||
// +build OMIT
|
||||
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
// START OMIT
|
||||
type MyBool bool
|
||||
const True = true
|
||||
const TypedTrue bool = true
|
||||
var mb MyBool
|
||||
mb = true // OK
|
||||
mb = True // OK
|
||||
mb = TypedTrue // Bad
|
||||
fmt.Println(mb)
|
||||
// STOP OMIT
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
// +build OMIT
|
||||
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
// START OMIT
|
||||
type MyComplex128 complex128
|
||||
const I = (0.0 + 1.0i)
|
||||
const TypedI complex128 = (0.0 + 1.0i)
|
||||
var mc MyComplex128
|
||||
mc = (0.0 + 1.0i) // OK
|
||||
mc = I // OK
|
||||
mc = TypedI // Bad
|
||||
fmt.Println(mc)
|
||||
// STOP OMIT
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
// +build OMIT
|
||||
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
const Two = 2.0 + 0i
|
||||
// START OMIT
|
||||
s := Two
|
||||
fmt.Printf("%T: %v\n", s, s)
|
||||
// STOP OMIT
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
// +build OMIT
|
||||
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
const Two = 2.0 + 0i
|
||||
// START OMIT
|
||||
var f float64
|
||||
var g float64 = Two
|
||||
f = Two
|
||||
fmt.Println(f, "and", g)
|
||||
// STOP OMIT
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
// +build OMIT
|
||||
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
// START OMIT
|
||||
fmt.Printf("%s", "Hello, 世界")
|
||||
// STOP OMIT
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
// +build OMIT
|
||||
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
const hello = "Hello, 世界"
|
||||
|
||||
func main() {
|
||||
// START OMIT
|
||||
fmt.Printf("%T: %v\n", "Hello, 世界", "Hello, 世界")
|
||||
fmt.Printf("%T: %v\n", hello, hello)
|
||||
// STOP OMIT
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
// +build OMIT
|
||||
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
type MyString string
|
||||
|
||||
const myStringHello MyString = "Hello, 世界"
|
||||
|
||||
func main() {
|
||||
// START OMIT
|
||||
fmt.Printf("%T: %v\n", myStringHello, myStringHello)
|
||||
// STOP OMIT
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
// +build OMIT
|
||||
|
||||
package main
|
||||
|
||||
func main() {
|
||||
// START OMIT
|
||||
const MaxUint uint = -1 // Error: negative value
|
||||
// STOP OMIT
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
// +build OMIT
|
||||
|
||||
package main
|
||||
|
||||
func main() {
|
||||
// START OMIT
|
||||
const MaxUint uint = uint(-1) // Error: negative value
|
||||
// STOP OMIT
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
// +build OMIT
|
||||
|
||||
package main
|
||||
|
||||
func main() {
|
||||
// START OMIT
|
||||
var u uint
|
||||
var v = -1
|
||||
u = uint(v)
|
||||
// STOP OMIT
|
||||
_ = u
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
// +build OMIT
|
||||
|
||||
package main
|
||||
|
||||
func main() {
|
||||
// START OMIT
|
||||
var u uint
|
||||
const v = -1
|
||||
u = uint(v) // Error: negative value
|
||||
// STOP OMIT
|
||||
_ = u
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
// +build OMIT
|
||||
|
||||
package main
|
||||
|
||||
func main() {
|
||||
// START OMIT
|
||||
const MaxUint uint = ^0 // Error: overflow
|
||||
// STOP OMIT
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
// +build OMIT
|
||||
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
// START OMIT
|
||||
const MaxUint = ^uint(0)
|
||||
fmt.Printf("%x\n", MaxUint)
|
||||
// STOP OMIT
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
// +build OMIT
|
||||
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
// START OMIT
|
||||
type MyFloat64 float64
|
||||
const Zero = 0.0
|
||||
const TypedZero float64 = 0.0
|
||||
var mf MyFloat64
|
||||
mf = 0.0 // OK
|
||||
mf = Zero // OK
|
||||
mf = TypedZero // Bad
|
||||
fmt.Println(mf)
|
||||
// STOP OMIT
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
// +build OMIT
|
||||
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
const Zero = 0.0
|
||||
const TypedZero float64 = 0.0
|
||||
// START OMIT
|
||||
var f32 float32
|
||||
f32 = 0.0
|
||||
f32 = Zero // OK: Zero is untyped
|
||||
f32 = TypedZero // Bad: TypedZero is float64 not float32.
|
||||
fmt.Println(f32)
|
||||
// STOP OMIT
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
// +build OMIT
|
||||
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
const Huge = 1e1000
|
||||
// START OMIT
|
||||
fmt.Println(Huge)
|
||||
// STOP OMIT
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
// +build OMIT
|
||||
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
const Huge = 1e1000
|
||||
// START OMIT
|
||||
fmt.Println(Huge / 1e999)
|
||||
// STOP OMIT
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
// +build OMIT
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// START OMIT
|
||||
pi := math.Pi
|
||||
fmt.Println(pi)
|
||||
// STOP OMIT
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
// +build OMIT
|
||||
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
// START OMIT
|
||||
type MyInt int
|
||||
const Three = 3
|
||||
const TypedThree int = 3
|
||||
var mi MyInt
|
||||
mi = 3 // OK
|
||||
mi = Three // OK
|
||||
mi = TypedThree // Bad
|
||||
fmt.Println(mi)
|
||||
// STOP OMIT
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
// +build OMIT
|
||||
|
||||
package main
|
||||
|
||||
func main() {
|
||||
// START OMIT
|
||||
var i8 int8 = 128 // Error: too large.
|
||||
// STOP OMIT
|
||||
_ = i8
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
// +build OMIT
|
||||
|
||||
package main
|
||||
|
||||
func main() {
|
||||
// START OMIT
|
||||
var u8 uint8 = -1 // Error: negative value.
|
||||
// STOP OMIT
|
||||
_ = u8
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
// +build OMIT
|
||||
|
||||
package main
|
||||
|
||||
func main() {
|
||||
// START OMIT
|
||||
type Char byte
|
||||
var c Char = '世' // Error: '世' has value 0x4e16, too large.
|
||||
// STOP OMIT
|
||||
_ = c
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
// +build OMIT
|
||||
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
// START OMIT
|
||||
var f float32 = 1
|
||||
var i int = 1.000
|
||||
var u uint32 = 1e3 - 99.0*10.0 - 9
|
||||
var c float64 = '\x01'
|
||||
var p uintptr = '\u0001'
|
||||
var r complex64 = 'b' - 'a'
|
||||
var b byte = 1.0 + 3i - 3.0i
|
||||
|
||||
fmt.Println(f, i, u, c, p, r, b)
|
||||
// STOP OMIT
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
// +build OMIT
|
||||
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
// START OMIT
|
||||
var f = 'a' * 1.5
|
||||
fmt.Println(f)
|
||||
// STOP OMIT
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
// +build OMIT
|
||||
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
const typedHello string = "Hello, 世界"
|
||||
|
||||
func main() {
|
||||
// START OMIT
|
||||
var s string
|
||||
s = typedHello
|
||||
fmt.Println(s)
|
||||
// STOP OMIT
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
// +build OMIT
|
||||
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
const typedHello string = "Hello, 世界"
|
||||
|
||||
func main() {
|
||||
// START OMIT
|
||||
type MyString string
|
||||
var m MyString
|
||||
m = typedHello // Type error
|
||||
fmt.Println(m)
|
||||
// STOP OMIT
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
// +build OMIT
|
||||
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
const typedHello string = "Hello, 世界"
|
||||
|
||||
func main() {
|
||||
type MyString string
|
||||
var m MyString
|
||||
// START OMIT
|
||||
const myStringHello MyString = "Hello, 世界"
|
||||
m = myStringHello // OK
|
||||
fmt.Println(m)
|
||||
// STOP OMIT
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
// +build OMIT
|
||||
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
const typedHello string = "Hello, 世界"
|
||||
|
||||
func main() {
|
||||
type MyString string
|
||||
var m MyString
|
||||
// START OMIT
|
||||
m = MyString(typedHello)
|
||||
fmt.Println(m)
|
||||
// STOP OMIT
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
// +build OMIT
|
||||
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
// START OMIT
|
||||
fmt.Printf("%T %v\n", 0, 0)
|
||||
fmt.Printf("%T %v\n", 0.0, 0.0)
|
||||
fmt.Printf("%T %v\n", 'x', 'x')
|
||||
fmt.Printf("%T %v\n", 0i, 0i)
|
||||
// STOP OMIT
|
||||
}
|
|
@ -1,142 +0,0 @@
|
|||
# Contexts and structs
|
||||
24 Feb 2021
|
||||
Tags: context, cancelation, cancellation
|
||||
|
||||
Jean de Klerk, Matt T. Proud
|
||||
|
||||
## Introduction
|
||||
|
||||
In many Go APIs, especially modern ones, the first argument to functions and methods is often [`context.Context`](https://golang.org/pkg/context/). Context provides a means of transmitting deadlines, caller cancellations, and other request-scoped values across API boundaries and between processes. It is often used when a library interacts — directly or transitively — with remote servers, such as databases, APIs, and the like.
|
||||
|
||||
The [documentation for context](https://golang.org/pkg/context/) states:
|
||||
|
||||
> Contexts should not be stored inside a struct type, but instead passed to each function that needs it.
|
||||
|
||||
This article expands on that advice with reasons and examples describing why it's important to pass Context rather than store it in another type. It also highlights a rare case where storing Context in a struct type may make sense, and how to do so safely.
|
||||
|
||||
## Prefer contexts passed as arguments
|
||||
|
||||
To understand the advice to not store context in structs, let's consider the preferred context-as-argument approach:
|
||||
|
||||
```
|
||||
// Worker fetches and adds works to a remote work orchestration server.
|
||||
type Worker struct { /* … */ }
|
||||
|
||||
type Work struct { /* … */ }
|
||||
|
||||
func New() *Worker {
|
||||
return &Worker{}
|
||||
}
|
||||
|
||||
func (w *Worker) Fetch(ctx context.Context) (*Work, error) {
|
||||
_ = ctx // A per-call ctx is used for cancellation, deadlines, and metadata.
|
||||
}
|
||||
|
||||
func (w *Worker) Process(ctx context.Context, work *Work) error {
|
||||
_ = ctx // A per-call ctx is used for cancellation, deadlines, and metadata.
|
||||
}
|
||||
```
|
||||
|
||||
Here, the `(*Worker).Fetch` and `(*Worker).Process` methods both accept a context directly. With this pass-as-argument design, users can set per-call deadlines, cancellation, and metadata. And, it's clear how the `context.Context` passed to each method will be used: there's no expectation that a `context.Context` passed to one method will be used by any other method. This is because the context is scoped to as small an operation as it needs to be, which greatly increases the utility and clarity of `context` in this package.
|
||||
|
||||
## Storing context in structs leads to confusion
|
||||
|
||||
Let's inspect again the `Worker` example above with the disfavored context-in-struct approach. The problem with it is that when you store the context in a struct, you obscure lifetime to the callers, or worse intermingle two scopes together in unpredictable ways:
|
||||
|
||||
```
|
||||
type Worker struct {
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
func New(ctx context.Context) *Worker {
|
||||
return &Worker{ctx: ctx}
|
||||
}
|
||||
|
||||
func (w *Worker) Fetch() (*Work, error) {
|
||||
_ = w.ctx // A shared w.ctx is used for cancellation, deadlines, and metadata.
|
||||
}
|
||||
|
||||
func (w *Worker) Process(work *Work) error {
|
||||
_ = w.ctx // A shared w.ctx is used for cancellation, deadlines, and metadata.
|
||||
}
|
||||
```
|
||||
|
||||
The `(*Worker).Fetch` and `(*Worker).Process` method both use a context stored in Worker. This prevents the callers of Fetch and Process (which may themselves have different contexts) from specifying a deadline, requesting cancellation, and attaching metadata on a per-call basis. For example: the user is unable to provide a deadline just for `(*Worker).Fetch`, or cancel just the `(*Worker).Process` call. The caller's lifetime is intermingled with a shared context, and the context is scoped to the lifetime where the `Worker` is created.
|
||||
|
||||
The API is also much more confusing to users compared to the pass-as-argument approach. Users might ask themselves:
|
||||
|
||||
- Since `New` takes a `context.Context`, is the constructor doing work that needs cancelation or deadlines?
|
||||
- Does the `context.Context` passed in to `New` apply to work in `(*Worker).Fetch` and `(*Worker).Process`? Neither? One but not the other?
|
||||
|
||||
The API would need a good deal of documentation to explicitly tell the user exactly what the `context.Context` is used for. The user might also have to read code rather than being able to rely on the structure of the API conveys.
|
||||
|
||||
And, finally, it can be quite dangerous to design a production-grade server whose requests don't each have a context and thus can't adequately honor cancellation. Without the ability to set per-call deadlines, [your process could backlog](https://sre.google/sre-book/handling-overload/) and exhaust its resources (like memory)!
|
||||
|
||||
## Exception to the rule: preserving backwards compatibility
|
||||
|
||||
When Go 1.7 — which [introduced context.Context](https://golang.org/doc/go1.7) — was released, a large number of APIs had to add context support in backwards compatible ways. For example, [`net/http`'s `Client` methods](https://golang.org/pkg/net/http/), like `Get` and `Do`, were excellent candidates for context. Each external request sent with these methods would benefit from having the deadline, cancellation, and metadata support that came with `context.Context`.
|
||||
|
||||
There are two approaches for adding support for `context.Context` in backwards compatible ways: including a context in a struct, as we'll see in a moment, and duplicating functions, with duplicates accepting `context.Context` and having `Context` as their function name suffix. The duplicate approach should be preferred over the context-in-struct, and is further discussed in [Keeping your modules compatible](https://blog.golang.org/module-compatibility). However, in some cases it's impractical: for example, if your API exposes a large number of functions, then duplicating them all might be infeasible.
|
||||
|
||||
The `net/http` package chose the context-in-struct approach, which provides a useful case study. Let's look at `net/http`'s `Do`. Prior to the introduction of `context.Context`, `Do` was defined as follows:
|
||||
|
||||
```
|
||||
// Do sends an HTTP request and returns an HTTP response [...]
|
||||
func (c *Client) Do(req *Request) (*Response, error)
|
||||
```
|
||||
|
||||
After Go 1.7, `Do` might have looked like the following, if not for the fact that it would break backwards compatibility:
|
||||
|
||||
```
|
||||
// Do sends an HTTP request and returns an HTTP response [...]
|
||||
func (c *Client) Do(ctx context.Context, req *Request) (*Response, error)
|
||||
```
|
||||
|
||||
But, preserving the backwards compatibility and adhering to the [Go 1 promise of compatibility](https://golang.org/doc/go1compat) is crucial for the standard library. So, instead, the maintainers chose to add a `context.Context` on the `http.Request` struct in order to allow support `context.Context` without breaking backwards compatibility:
|
||||
|
||||
```
|
||||
// A Request represents an HTTP request received by a server or to be sent by a client.
|
||||
// ...
|
||||
type Request struct {
|
||||
ctx context.Context
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
// NewRequestWithContext returns a new Request given a method, URL, and optional
|
||||
// body.
|
||||
// [...]
|
||||
// The given ctx is used for the lifetime of the Request.
|
||||
func NewRequestWithContext(ctx context.Context, method, url string, body io.Reader) (*Request, error) {
|
||||
// Simplified for brevity of this article.
|
||||
return &Request{
|
||||
ctx: ctx,
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
// Do sends an HTTP request and returns an HTTP response [...]
|
||||
func (c *Client) Do(req *Request) (*Response, error)
|
||||
```
|
||||
|
||||
When retrofitting your API to support context, it may make sense to add a `context.Context` to a struct, as above. However, remember to first consider duplicating your functions, which allows retrofitting `context.Context` in a backwards compatibility without sacrificing utility and comprehension. For example:
|
||||
|
||||
```
|
||||
// Call uses context.Background internally; to specify the context, use
|
||||
// CallContext.
|
||||
func (c *Client) Call() error {
|
||||
return c.CallContext(context.Background())
|
||||
}
|
||||
|
||||
func (c *Client) CallContext(ctx context.Context) error {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
## Conclusion
|
||||
|
||||
Context makes it easy to propagate important cross-library and cross-API information down a calling stack. But, it must be used consistently and clearly in order to remain comprehensible, easy to debug, and effective.
|
||||
|
||||
When passed as the first argument in a method rather than stored in a struct type, users can take full advantage of its extensibility in order to build a powerful tree of cancelation, deadline, and metadata information through the call stack. And, best of all, its scope is clearly understood when it's passed in as an argument, leading to clear comprehension and debuggability up and down the stack.
|
||||
|
||||
When designing an API with context, remember the advice: pass `context.Context` in as an argument; don't store it in structs.
|
|
@ -1,225 +0,0 @@
|
|||
# Go Concurrency Patterns: Context
|
||||
29 Jul 2014
|
||||
Tags: concurrency, cancelation, cancellation, context
|
||||
Summary: An introduction to the Go context package.
|
||||
|
||||
Sameer Ajmani
|
||||
|
||||
## Introduction
|
||||
|
||||
In Go servers, each incoming request is handled in its own goroutine.
|
||||
Request handlers often start additional goroutines to access backends such as
|
||||
databases and RPC services.
|
||||
The set of goroutines working on a request typically needs access to
|
||||
request-specific values such as the identity of the end user, authorization
|
||||
tokens, and the request's deadline.
|
||||
When a request is canceled or times out, all the goroutines working on that
|
||||
request should exit quickly so the system can reclaim any resources they are
|
||||
using.
|
||||
|
||||
At Google, we developed a `context` package that makes it easy to pass
|
||||
request-scoped values, cancelation signals, and deadlines across API boundaries
|
||||
to all the goroutines involved in handling a request.
|
||||
The package is publicly available as
|
||||
[context](https://golang.org/pkg/context).
|
||||
This article describes how to use the package and provides a complete working
|
||||
example.
|
||||
|
||||
## Context
|
||||
|
||||
The core of the `context` package is the `Context` type:
|
||||
|
||||
.code context/interface.go /A Context/,/^}/
|
||||
|
||||
(This description is condensed; the
|
||||
[godoc](https://golang.org/pkg/context) is authoritative.)
|
||||
|
||||
The `Done` method returns a channel that acts as a cancelation signal to
|
||||
functions running on behalf of the `Context`: when the channel is closed, the
|
||||
functions should abandon their work and return.
|
||||
The `Err` method returns an error indicating why the `Context` was canceled.
|
||||
The [Pipelines and Cancelation](/pipelines) article discusses the `Done`
|
||||
channel idiom in more detail.
|
||||
|
||||
A `Context` does _not_ have a `Cancel` method for the same reason the `Done`
|
||||
channel is receive-only: the function receiving a cancelation signal is usually
|
||||
not the one that sends the signal.
|
||||
In particular, when a parent operation starts goroutines for sub-operations,
|
||||
those sub-operations should not be able to cancel the parent.
|
||||
Instead, the `WithCancel` function (described below) provides a way to cancel a
|
||||
new `Context` value.
|
||||
|
||||
A `Context` is safe for simultaneous use by multiple goroutines.
|
||||
Code can pass a single `Context` to any number of goroutines and cancel that
|
||||
`Context` to signal all of them.
|
||||
|
||||
The `Deadline` method allows functions to determine whether they should start
|
||||
work at all; if too little time is left, it may not be worthwhile.
|
||||
Code may also use a deadline to set timeouts for I/O operations.
|
||||
|
||||
`Value` allows a `Context` to carry request-scoped data.
|
||||
That data must be safe for simultaneous use by multiple goroutines.
|
||||
|
||||
### Derived contexts
|
||||
|
||||
The `context` package provides functions to _derive_ new `Context` values from
|
||||
existing ones.
|
||||
These values form a tree: when a `Context` is canceled, all `Contexts` derived
|
||||
from it are also canceled.
|
||||
|
||||
`Background` is the root of any `Context` tree; it is never canceled:
|
||||
|
||||
.code context/interface.go /Background returns/,/func Background/
|
||||
|
||||
`WithCancel` and `WithTimeout` return derived `Context` values that can be
|
||||
canceled sooner than the parent `Context`.
|
||||
The `Context` associated with an incoming request is typically canceled when the
|
||||
request handler returns.
|
||||
`WithCancel` is also useful for canceling redundant requests when using multiple
|
||||
replicas.
|
||||
`WithTimeout` is useful for setting a deadline on requests to backend servers:
|
||||
|
||||
.code context/interface.go /WithCancel/,/func WithTimeout/
|
||||
|
||||
`WithValue` provides a way to associate request-scoped values with a `Context`:
|
||||
|
||||
.code context/interface.go /WithValue/,/func WithValue/
|
||||
|
||||
The best way to see how to use the `context` package is through a worked
|
||||
example.
|
||||
|
||||
## Example: Google Web Search
|
||||
|
||||
Our example is an HTTP server that handles URLs like
|
||||
`/search?q=golang&timeout=1s` by forwarding the query "golang" to the
|
||||
[Google Web Search API](https://developers.google.com/web-search/docs/) and
|
||||
rendering the results.
|
||||
The `timeout` parameter tells the server to cancel the request after that
|
||||
duration elapses.
|
||||
|
||||
The code is split across three packages:
|
||||
|
||||
- [server](context/server/server.go) provides the `main` function and the handler for `/search`.
|
||||
- [userip](context/userip/userip.go) provides functions for extracting a user IP address from a request and associating it with a `Context`.
|
||||
- [google](context/google/google.go) provides the `Search` function for sending a query to Google.
|
||||
|
||||
### The server program
|
||||
|
||||
The [server](context/server/server.go) program handles requests like
|
||||
`/search?q=golang` by serving the first few Google search results for `golang`.
|
||||
It registers `handleSearch` to handle the `/search` endpoint.
|
||||
The handler creates an initial `Context` called `ctx` and arranges for it to be
|
||||
canceled when the handler returns.
|
||||
If the request includes the `timeout` URL parameter, the `Context` is canceled
|
||||
automatically when the timeout elapses:
|
||||
|
||||
.code context/server/server.go /func handleSearch/,/defer cancel/
|
||||
|
||||
The handler extracts the query from the request and extracts the client's IP
|
||||
address by calling on the `userip` package.
|
||||
The client's IP address is needed for backend requests, so `handleSearch`
|
||||
attaches it to `ctx`:
|
||||
|
||||
.code context/server/server.go /Check the search query/,/userip.NewContext/
|
||||
|
||||
The handler calls `google.Search` with `ctx` and the `query`:
|
||||
|
||||
.code context/server/server.go /Run the Google search/,/elapsed/
|
||||
|
||||
If the search succeeds, the handler renders the results:
|
||||
|
||||
.code context/server/server.go /resultsTemplate/,/}$/
|
||||
|
||||
### Package userip
|
||||
|
||||
The [userip](context/userip/userip.go) package provides functions for
|
||||
extracting a user IP address from a request and associating it with a `Context`.
|
||||
A `Context` provides a key-value mapping, where the keys and values are both of
|
||||
type `interface{}`.
|
||||
Key types must support equality, and values must be safe for simultaneous use by
|
||||
multiple goroutines.
|
||||
Packages like `userip` hide the details of this mapping and provide
|
||||
strongly-typed access to a specific `Context` value.
|
||||
|
||||
To avoid key collisions, `userip` defines an unexported type `key` and uses
|
||||
a value of this type as the context key:
|
||||
|
||||
.code context/userip/userip.go /The key type/,/const userIPKey/
|
||||
|
||||
`FromRequest` extracts a `userIP` value from an `http.Request`:
|
||||
|
||||
.code context/userip/userip.go /func FromRequest/,/}/
|
||||
|
||||
`NewContext` returns a new `Context` that carries a provided `userIP` value:
|
||||
|
||||
.code context/userip/userip.go /func NewContext/,/}/
|
||||
|
||||
`FromContext` extracts a `userIP` from a `Context`:
|
||||
|
||||
.code context/userip/userip.go /func FromContext/,/}/
|
||||
|
||||
### Package google
|
||||
|
||||
The [google.Search](context/google/google.go) function makes an HTTP request
|
||||
to the [Google Web Search API](https://developers.google.com/web-search/docs/)
|
||||
and parses the JSON-encoded result.
|
||||
It accepts a `Context` parameter `ctx` and returns immediately if `ctx.Done` is
|
||||
closed while the request is in flight.
|
||||
|
||||
The Google Web Search API request includes the search query and the user IP as
|
||||
query parameters:
|
||||
|
||||
.code context/google/google.go /func Search/,/q.Encode/
|
||||
|
||||
`Search` uses a helper function, `httpDo`, to issue the HTTP request and cancel
|
||||
it if `ctx.Done` is closed while the request or response is being processed.
|
||||
`Search` passes a closure to `httpDo` handle the HTTP response:
|
||||
|
||||
.code context/google/google.go /var results/,/return results/
|
||||
|
||||
The `httpDo` function runs the HTTP request and processes its response in a new
|
||||
goroutine.
|
||||
It cancels the request if `ctx.Done` is closed before the goroutine exits:
|
||||
|
||||
.code context/google/google.go /func httpDo/,/^}/
|
||||
|
||||
## Adapting code for Contexts
|
||||
|
||||
Many server frameworks provide packages and types for carrying request-scoped
|
||||
values.
|
||||
We can define new implementations of the `Context` interface to bridge between
|
||||
code using existing frameworks and code that expects a `Context` parameter.
|
||||
|
||||
For example, Gorilla's
|
||||
[github.com/gorilla/context](http://www.gorillatoolkit.org/pkg/context)
|
||||
package allows handlers to associate data with incoming requests by providing a
|
||||
mapping from HTTP requests to key-value pairs.
|
||||
In [gorilla.go](context/gorilla/gorilla.go), we provide a `Context`
|
||||
implementation whose `Value` method returns the values associated with a
|
||||
specific HTTP request in the Gorilla package.
|
||||
|
||||
Other packages have provided cancelation support similar to `Context`.
|
||||
For example, [Tomb](https://godoc.org/gopkg.in/tomb.v2) provides a `Kill`
|
||||
method that signals cancelation by closing a `Dying` channel.
|
||||
`Tomb` also provides methods to wait for those goroutines to exit, similar to
|
||||
`sync.WaitGroup`.
|
||||
In [tomb.go](context/tomb/tomb.go), we provide a `Context` implementation that
|
||||
is canceled when either its parent `Context` is canceled or a provided `Tomb` is
|
||||
killed.
|
||||
|
||||
## Conclusion
|
||||
|
||||
At Google, we require that Go programmers pass a `Context` parameter as the
|
||||
first argument to every function on the call path between incoming and outgoing
|
||||
requests.
|
||||
This allows Go code developed by many different teams to interoperate well.
|
||||
It provides simple control over timeouts and cancelation and ensures that
|
||||
critical values like security credentials transit Go programs properly.
|
||||
|
||||
Server frameworks that want to build on `Context` should provide implementations
|
||||
of `Context` to bridge between their packages and those that expect a `Context`
|
||||
parameter.
|
||||
Their client libraries would then accept a `Context` from the calling code.
|
||||
By establishing a common interface for request-scoped data and cancelation,
|
||||
`Context` makes it easier for package developers to share code for creating
|
||||
scalable services.
|
|
@ -1,94 +0,0 @@
|
|||
// +build OMIT
|
||||
|
||||
// Package google provides a function to do Google searches using the Google Web
|
||||
// Search API. See https://developers.google.com/web-search/docs/
|
||||
//
|
||||
// This package is an example to accompany https://blog.golang.org/context.
|
||||
// It is not intended for use by others.
|
||||
//
|
||||
// Google has since disabled its search API,
|
||||
// and so this package is no longer useful.
|
||||
package google
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"golang.org/x/blog/content/context/userip"
|
||||
)
|
||||
|
||||
// Results is an ordered list of search results.
|
||||
type Results []Result
|
||||
|
||||
// A Result contains the title and URL of a search result.
|
||||
type Result struct {
|
||||
Title, URL string
|
||||
}
|
||||
|
||||
// Search sends query to Google search and returns the results.
|
||||
func Search(ctx context.Context, query string) (Results, error) {
|
||||
// Prepare the Google Search API request.
|
||||
req, err := http.NewRequest("GET", "https://ajax.googleapis.com/ajax/services/search/web?v=1.0", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
q := req.URL.Query()
|
||||
q.Set("q", query)
|
||||
|
||||
// If ctx is carrying the user IP address, forward it to the server.
|
||||
// Google APIs use the user IP to distinguish server-initiated requests
|
||||
// from end-user requests.
|
||||
if userIP, ok := userip.FromContext(ctx); ok {
|
||||
q.Set("userip", userIP.String())
|
||||
}
|
||||
req.URL.RawQuery = q.Encode()
|
||||
|
||||
// Issue the HTTP request and handle the response. The httpDo function
|
||||
// cancels the request if ctx.Done is closed.
|
||||
var results Results
|
||||
err = httpDo(ctx, req, func(resp *http.Response, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// Parse the JSON search result.
|
||||
// https://developers.google.com/web-search/docs/#fonje
|
||||
var data struct {
|
||||
ResponseData struct {
|
||||
Results []struct {
|
||||
TitleNoFormatting string
|
||||
URL string
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, res := range data.ResponseData.Results {
|
||||
results = append(results, Result{Title: res.TitleNoFormatting, URL: res.URL})
|
||||
}
|
||||
return nil
|
||||
})
|
||||
// httpDo waits for the closure we provided to return, so it's safe to
|
||||
// read results here.
|
||||
return results, err
|
||||
}
|
||||
|
||||
// httpDo issues the HTTP request and calls f with the response. If ctx.Done is
|
||||
// closed while the request or f is running, httpDo cancels the request, waits
|
||||
// for f to exit, and returns ctx.Err. Otherwise, httpDo returns f's error.
|
||||
func httpDo(ctx context.Context, req *http.Request, f func(*http.Response, error) error) error {
|
||||
// Run the HTTP request in a goroutine and pass the response to f.
|
||||
c := make(chan error, 1)
|
||||
req = req.WithContext(ctx)
|
||||
go func() { c <- f(http.DefaultClient.Do(req)) }()
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
<-c // Wait for f to return.
|
||||
return ctx.Err()
|
||||
case err := <-c:
|
||||
return err
|
||||
}
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
// +build OMIT
|
||||
|
||||
// Package gorilla provides a go.net/context.Context implementation whose Value
|
||||
// method returns the values associated with a specific HTTP request in the
|
||||
// github.com/gorilla/context package.
|
||||
package gorilla
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
gcontext "github.com/gorilla/context"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
// NewContext returns a Context whose Value method returns values associated
|
||||
// with req using the Gorilla context package:
|
||||
// http://www.gorillatoolkit.org/pkg/context
|
||||
func NewContext(parent context.Context, req *http.Request) context.Context {
|
||||
return &wrapper{parent, req}
|
||||
}
|
||||
|
||||
type wrapper struct {
|
||||
context.Context
|
||||
req *http.Request
|
||||
}
|
||||
|
||||
type key int
|
||||
|
||||
const reqKey key = 0
|
||||
|
||||
// Value returns Gorilla's context package's value for this Context's request
|
||||
// and key. It delegates to the parent Context if there is no such value.
|
||||
func (ctx *wrapper) Value(key interface{}) interface{} {
|
||||
if key == reqKey {
|
||||
return ctx.req
|
||||
}
|
||||
if val, ok := gcontext.GetOk(ctx.req, key); ok {
|
||||
return val
|
||||
}
|
||||
return ctx.Context.Value(key)
|
||||
}
|
||||
|
||||
// HTTPRequest returns the *http.Request associated with ctx using NewContext,
|
||||
// if any.
|
||||
func HTTPRequest(ctx context.Context) (*http.Request, bool) {
|
||||
// We cannot use ctx.(*wrapper).req to get the request because ctx may
|
||||
// be a Context derived from a *wrapper. Instead, we use Value to
|
||||
// access the request if it is anywhere up the Context tree.
|
||||
req, ok := ctx.Value(reqKey).(*http.Request)
|
||||
return req, ok
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
// +build OMIT
|
||||
|
||||
package context
|
||||
|
||||
import "time"
|
||||
|
||||
// A Context carries a deadline, cancelation signal, and request-scoped values
|
||||
// across API boundaries. Its methods are safe for simultaneous use by multiple
|
||||
// goroutines.
|
||||
type Context interface {
|
||||
// Done returns a channel that is closed when this Context is canceled
|
||||
// or times out.
|
||||
Done() <-chan struct{}
|
||||
|
||||
// Err indicates why this context was canceled, after the Done channel
|
||||
// is closed.
|
||||
Err() error
|
||||
|
||||
// Deadline returns the time when this Context will be canceled, if any.
|
||||
Deadline() (deadline time.Time, ok bool)
|
||||
|
||||
// Value returns the value associated with key or nil if none.
|
||||
Value(key interface{}) interface{}
|
||||
}
|
||||
|
||||
// WithCancel returns a copy of parent whose Done channel is closed as soon as
|
||||
// parent.Done is closed or cancel is called.
|
||||
func WithCancel(parent Context) (ctx Context, cancel CancelFunc)
|
||||
|
||||
// A CancelFunc cancels a Context.
|
||||
type CancelFunc func()
|
||||
|
||||
// WithTimeout returns a copy of parent whose Done channel is closed as soon as
|
||||
// parent.Done is closed, cancel is called, or timeout elapses. The new
|
||||
// Context's Deadline is the sooner of now+timeout and the parent's deadline, if
|
||||
// any. If the timer is still running, the cancel function releases its
|
||||
// resources.
|
||||
func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)
|
||||
|
||||
// WithValue returns a copy of parent whose Value method returns val for key.
|
||||
func WithValue(parent Context, key interface{}, val interface{}) Context
|
||||
|
||||
// Background returns an empty Context. It is never canceled, has no deadline,
|
||||
// and has no values. Background is typically used in main, init, and tests,
|
||||
// and as the top-level Context for incoming requests.
|
||||
func Background() Context
|
|
@ -1,100 +0,0 @@
|
|||
// +build OMIT
|
||||
|
||||
// The server program issues Google search requests and demonstrates the use of
|
||||
// the go.net Context API. It serves on port 8080.
|
||||
//
|
||||
// The /search endpoint accepts these query params:
|
||||
// q=the Google search query
|
||||
// timeout=a timeout for the request, in time.Duration format
|
||||
//
|
||||
// For example, http://localhost:8080/search?q=golang&timeout=1s serves the
|
||||
// first few Google search results for "golang" or a "deadline exceeded" error
|
||||
// if the timeout expires.
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"html/template"
|
||||
"log"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"golang.org/x/blog/content/context/google"
|
||||
"golang.org/x/blog/content/context/userip"
|
||||
)
|
||||
|
||||
func main() {
|
||||
http.HandleFunc("/search", handleSearch)
|
||||
log.Fatal(http.ListenAndServe(":8080", nil))
|
||||
}
|
||||
|
||||
// handleSearch handles URLs like /search?q=golang&timeout=1s by forwarding the
|
||||
// query to google.Search. If the query param includes timeout, the search is
|
||||
// canceled after that duration elapses.
|
||||
func handleSearch(w http.ResponseWriter, req *http.Request) {
|
||||
// ctx is the Context for this handler. Calling cancel closes the
|
||||
// ctx.Done channel, which is the cancellation signal for requests
|
||||
// started by this handler.
|
||||
var (
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
)
|
||||
timeout, err := time.ParseDuration(req.FormValue("timeout"))
|
||||
if err == nil {
|
||||
// The request has a timeout, so create a context that is
|
||||
// canceled automatically when the timeout expires.
|
||||
ctx, cancel = context.WithTimeout(context.Background(), timeout)
|
||||
} else {
|
||||
ctx, cancel = context.WithCancel(context.Background())
|
||||
}
|
||||
defer cancel() // Cancel ctx as soon as handleSearch returns.
|
||||
|
||||
// Check the search query.
|
||||
query := req.FormValue("q")
|
||||
if query == "" {
|
||||
http.Error(w, "no query", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Store the user IP in ctx for use by code in other packages.
|
||||
userIP, err := userip.FromRequest(req)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
ctx = userip.NewContext(ctx, userIP)
|
||||
|
||||
// Run the Google search and print the results.
|
||||
start := time.Now()
|
||||
results, err := google.Search(ctx, query)
|
||||
elapsed := time.Since(start)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
if err := resultsTemplate.Execute(w, struct {
|
||||
Results google.Results
|
||||
Timeout, Elapsed time.Duration
|
||||
}{
|
||||
Results: results,
|
||||
Timeout: timeout,
|
||||
Elapsed: elapsed,
|
||||
}); err != nil {
|
||||
log.Print(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var resultsTemplate = template.Must(template.New("results").Parse(`
|
||||
<html>
|
||||
<head/>
|
||||
<body>
|
||||
<ol>
|
||||
{{range .Results}}
|
||||
<li>{{.Title}} - <a href="{{.URL}}">{{.URL}}</a></li>
|
||||
{{end}}
|
||||
</ol>
|
||||
<p>{{len .Results}} results in {{.Elapsed}}; timeout {{.Timeout}}</p>
|
||||
</body>
|
||||
</html>
|
||||
`))
|
|
@ -1,24 +0,0 @@
|
|||
// +build OMIT
|
||||
|
||||
// Package tomb provides a Context implementation that is canceled when either
|
||||
// its parent Context is canceled or a provided Tomb is killed.
|
||||
package tomb
|
||||
|
||||
import (
|
||||
"golang.org/x/net/context"
|
||||
tomb "gopkg.in/tomb.v2"
|
||||
)
|
||||
|
||||
// NewContext returns a Context that is canceled either when parent is canceled
|
||||
// or when t is Killed.
|
||||
func NewContext(parent context.Context, t *tomb.Tomb) context.Context {
|
||||
ctx, cancel := context.WithCancel(parent)
|
||||
go func() {
|
||||
select {
|
||||
case <-t.Dying():
|
||||
cancel()
|
||||
case <-ctx.Done():
|
||||
}
|
||||
}()
|
||||
return ctx
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
// +build OMIT
|
||||
|
||||
// Package userip provides functions for extracting a user IP address from a
|
||||
// request and associating it with a Context.
|
||||
//
|
||||
// This package is an example to accompany https://blog.golang.org/context.
|
||||
// It is not intended for use by others.
|
||||
package userip
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// FromRequest extracts the user IP address from req, if present.
|
||||
func FromRequest(req *http.Request) (net.IP, error) {
|
||||
ip, _, err := net.SplitHostPort(req.RemoteAddr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("userip: %q is not IP:port", req.RemoteAddr)
|
||||
}
|
||||
|
||||
userIP := net.ParseIP(ip)
|
||||
if userIP == nil {
|
||||
return nil, fmt.Errorf("userip: %q is not IP:port", req.RemoteAddr)
|
||||
}
|
||||
return userIP, nil
|
||||
}
|
||||
|
||||
// The key type is unexported to prevent collisions with context keys defined in
|
||||
// other packages.
|
||||
type key int
|
||||
|
||||
// userIPkey is the context key for the user IP address. Its value of zero is
|
||||
// arbitrary. If this package defined other context keys, they would have
|
||||
// different integer values.
|
||||
const userIPKey key = 0
|
||||
|
||||
// NewContext returns a new Context carrying userIP.
|
||||
func NewContext(ctx context.Context, userIP net.IP) context.Context {
|
||||
return context.WithValue(ctx, userIPKey, userIP)
|
||||
}
|
||||
|
||||
// FromContext extracts the user IP address from ctx, if present.
|
||||
func FromContext(ctx context.Context) (net.IP, bool) {
|
||||
// ctx.Value returns nil if ctx has no value for the key;
|
||||
// the net.IP type assertion returns ok=false for nil.
|
||||
userIP, ok := ctx.Value(userIPKey).(net.IP)
|
||||
return userIP, ok
|
||||
}
|
|
@ -1,395 +0,0 @@
|
|||
# Contribution Workshop
|
||||
9 Aug 2017
|
||||
Tags: community
|
||||
Summary: The Go contributor workshop trained new contributors at GopherCon.
|
||||
|
||||
Steve Francia
|
||||
|
||||
Cassandra Salisbury
|
||||
|
||||
Matt Broberg
|
||||
|
||||
Dmitri Shuralyov
|
||||
|
||||
## Event Overview
|
||||
|
||||
by [Steve](https://twitter.com/spf13)
|
||||
|
||||
During the community day at GopherCon, the Go team held two workshops
|
||||
where we worked with people to help them make their first contribution to the
|
||||
Go project. This was the first time the Go project has ever attempted anything
|
||||
like this. We had about 140 participants and about 35 people who volunteered as
|
||||
mentors. Mentors not only received warm fuzzy feelings for helping others, but
|
||||
also a very stylish Go Mentor trucker hat. We had contributors of all
|
||||
ages and experience levels coming from North and South America, Africa, Europe,
|
||||
Asia, and Australia. It was truly a worldwide effort of Gophers coming together
|
||||
at GopherCon.
|
||||
|
||||
One of our reasons for running the workshop was for it to act as a forcing
|
||||
function to make us improve our contributor experience. In preparation for the
|
||||
workshop, we rewrote our contributor guide, including adding a "troubleshooting"
|
||||
section and built a tool `go-contrib-init`, which automated the process of
|
||||
setting up a development environment to be able to contribute to Go.
|
||||
|
||||
For the workshop itself, we developed a presentation _"Contributing to Go,"_
|
||||
and a dashboard / scoreboard that was presented during the event. The
|
||||
scoreboard was designed to encourage us all to work together towards a common
|
||||
goal of seeing our collective score increase. Participants added 1, 2 or 3 points to
|
||||
the total score when they performed actions like registering an account, making
|
||||
a change list (also known as a CL, similar to a pull request),
|
||||
amending a CL, or submitting a CL.
|
||||
|
||||
.image contributor-workshop/image17.png
|
||||
|
||||
Brad Fitzpatrick, who stayed home from GopherCon this year, was ready and
|
||||
waiting to review all CLs submitted. He was so quick to review that many people
|
||||
thought he was an automated bot. Internally our team is now calling him
|
||||
"BradBot" mostly because we are in awe and a bit jealous.
|
||||
|
||||
.image contributor-workshop/image9.jpg
|
||||
.image contributor-workshop/image6.png
|
||||
|
||||
### Impact
|
||||
|
||||
We had a total of 65 CLs submitted from the people who participated in the
|
||||
workshop (within a week of the workshop). Of these, 44 were from contributors
|
||||
who had never previously contributed to any of the repos in the Go project.
|
||||
Half (22) of these contributions were already merged. Many of the others are
|
||||
waiting on the codebase to thaw as we are in the middle of a freeze for the
|
||||
upcoming 1.9 release. In addition to CLs, many contributed to the project in
|
||||
the form of bug reports,
|
||||
[gardening tasks](https://golang.org/wiki/Gardening), and other types
|
||||
of contributions.
|
||||
|
||||
The most common type of contribution was an example function to be used in the
|
||||
documentation. The [Go User survey](https://blog.golang.org/survey2016-results)
|
||||
identified that our documentation was significantly lacking examples. In the
|
||||
presentation, we asked users to find a package they loved and to add an example. In
|
||||
the Go project, examples are written as code in Go files
|
||||
(with specific naming) and the `go doc` tool displays them along side the documentation.
|
||||
This is a perfect first contribution as it's something that can be merged
|
||||
during a freeze, it's of critical importance to our users, and it's an addition
|
||||
that has a relatively narrow scope.
|
||||
|
||||
One of the examples added is that of creating a Stringer, one of the more
|
||||
widely used interfaces in Go.
|
||||
[CL 49270](https://golang.org/cl/49270/)
|
||||
|
||||
In addition to examples, many people contributed critical bug fixes including:
|
||||
|
||||
- [CL 48988](https://golang.org/cl/48988/) fixing [issue #21029](https://golang.org/issue/21029)
|
||||
- [CL 49050](https://golang.org/cl/49050/) fixing [issue #20054](https://golang.org/issue/20054)
|
||||
- [CL 49031](https://golang.org/cl/49031/) fixing [issue #20166](https://golang.org/issue/20166)
|
||||
- [CL 49170](https://golang.org/cl/49170/) fixing [issue #20877](https://golang.org/issue/20877)
|
||||
|
||||
Some people even surprised us by arriving with a bug in mind that they wanted
|
||||
to fix. Nikhita arrived ready to tackle
|
||||
[issue #20786](https://golang.org/issue/20786)
|
||||
and she did submitting
|
||||
[CL 48871](https://golang.org/cl/48871/),
|
||||
after which she tweeted:
|
||||
|
||||
.image contributor-workshop/image19.png
|
||||
|
||||
Not only were some great improvements made, but most importantly, we narrowed
|
||||
the gap between the core Go team and the broader community members. Many people
|
||||
on the Go team remarked that the community members were teaching them things
|
||||
about the Go project. People in the community (in person, and on Twitter)
|
||||
remarked that felt welcome to participate in the project.
|
||||
|
||||
.image contributor-workshop/image12.png
|
||||
.image contributor-workshop/image13.png
|
||||
.image contributor-workshop/image3.png
|
||||
|
||||
### Future
|
||||
|
||||
The event was successful well beyond our expectations. Sameer Ajmani, Go team
|
||||
manager said, "The contributor workshop was incredibly fun and educational–for
|
||||
the Go team. We cringed as users hit the rough edges in our process, and
|
||||
celebrated when they got up on the dashboard. The cheer when the group score
|
||||
hit 1000 was awesome."
|
||||
|
||||
We are looking into ways to make this workshop easier to run for future events
|
||||
(like meetups and conferences). Our biggest challenge is providing enough
|
||||
mentorship so that users feel supported. If you have any ideas or would like to
|
||||
help with this process please [let me know](mailto:spf@golang.org).
|
||||
|
||||
I've asked a few participants of the event to share their experiences below:
|
||||
|
||||
## My Contribution Experience
|
||||
|
||||
by [Cassandra](https://twitter.com/cassandraoid)
|
||||
|
||||
When I heard about the go-contrib workshop I was very excited and then I was
|
||||
extremely intimidated. I was encouraged by a member of the Go team to
|
||||
participate, so I thought what the heck.
|
||||
|
||||
As I walked into the room (let's be real, I ran into the room because I was
|
||||
running late) I was pleased to see the room was jam-packed. I looked around for
|
||||
people in Gopher caps, which was the main indicator they were teachers. I sat
|
||||
down at one of the 16 round tables that had two hats and three non-hats.
|
||||
Brought up my screen and was ready to roll…
|
||||
|
||||
Jess Frazelle stood up and started the presentation and provided the group with
|
||||
[a link](https://docs.google.com/presentation/d/1ap2fycBSgoo-jCswhK9lqgCIFroE1pYpsXC1ffYBCq4/edit#slide=id.p)
|
||||
to make it easy to follow.
|
||||
|
||||
.image contributor-workshop/image16.png
|
||||
|
||||
The murmurs grew from a deep undercurrent to a resounding melody of voices,
|
||||
people were getting their computers set up with Go, they were skipping ahead to
|
||||
make sure their GOPATH was set, and were… wait what's Gerrit?
|
||||
|
||||
Most of us had to get a little intro to Gerrit. I had no clue what it was, but
|
||||
luckily there was a handy slide. Jess explained that it was an alternative to
|
||||
GitHub with slightly more advanced code review tools. We then went through
|
||||
GitHub vs Geritt terminology, so we had better understanding of the process.
|
||||
|
||||
.image contributor-workshop/image10.png
|
||||
|
||||
Ok, now it was time to become a **freaking Go contributor**.
|
||||
|
||||
To make this more exciting than it already is, the Go team set up a game where
|
||||
we could track as a group how many points we could rack up based on the Gerrit
|
||||
score system.
|
||||
|
||||
.image contributor-workshop/image7.png
|
||||
|
||||
Seeing your name pop up on the board and listening to everyone's excitement was
|
||||
intoxicating. It also invoked a sense of teamwork that lead to a feeling of
|
||||
inclusion and feeling like you were truly a part of the Go community.
|
||||
|
||||
.image contributor-workshop/image11.png
|
||||
|
||||
In 6 steps a room of around 80 people were able to learn how to contribute to
|
||||
go within an hour. That's a feat!
|
||||
|
||||
It wasn't nearly as difficult as I anticipated and it wasn't out of scope for a
|
||||
total newbie. It fostered a sense of community in an active and tangible way as
|
||||
well as a sense of inclusion in the illustrious process of Go contributions.
|
||||
|
||||
I'd personally like to thank the Go Team, the Gopher mentors in hats, and my
|
||||
fellow participants for making it one of my most memorable moments at
|
||||
GopherCon.
|
||||
|
||||
## My Contribution Experience
|
||||
|
||||
by [Matt](https://twitter.com/mbbroberg)
|
||||
|
||||
I've always found programming languages to be intimidating. It's the code that
|
||||
enables the world to write code. Given the impact, surely smarter people than
|
||||
me should be working on it... but that fear was something to overcome. So when
|
||||
the opportunity to join a workshop to contribute to my new favorite programming
|
||||
language came up, I was excite to see how I could and how I could help. A month
|
||||
later, I'm now certain that anyone and everyone can (and should) contribute back to Go.
|
||||
|
||||
Here are my very verbose steps to go from 0 to 2 contributions to Go:
|
||||
|
||||
### The Setup
|
||||
|
||||
Given Go's use of Gerrit, I started by setting up my environment for it. [Jess Frazzelle's guide](https://docs.google.com/presentation/d/1ap2fycBSgoo-jCswhK9lqgCIFroE1pYpsXC1ffYBCq4/edit#slide=id.g1f953ef7df_0_9)
|
||||
is a great place to start to not miss a step.
|
||||
|
||||
The real fun starts when you clone the Go repo. Ironically, you don't hack on
|
||||
Go under `$GOPATH`, so I put it in my other workspace (which is `~/Develop`).
|
||||
|
||||
cd $DEV # That's my source code folder outside of $GOPATH
|
||||
git clone --depth 1 https://go.googlesource.com/go
|
||||
|
||||
Then install the handy dandy helper tool, `go-contrib-init`:
|
||||
|
||||
go get -u golang.org/x/tools/cmd/go-contrib-init
|
||||
|
||||
Now you can run `go-contrib-init` from the `go/` folder we cloned above and see
|
||||
whether or not we're ready to contribute. But hold on if you're following along,
|
||||
you're not ready just yet.
|
||||
|
||||
Next, install `codereview` so you can participate in a Gerrit code review:
|
||||
|
||||
go get -u golang.org/x/review/git-codereview
|
||||
|
||||
This package includes `git change` and `git mail` which will replace your
|
||||
normal workflow of `git commit` and `git push` respectively.
|
||||
|
||||
Okay, installations are out of the way. Now setup your [Gerrit account here](https://go-review.googlesource.com/settings/#Profile),
|
||||
then [sign the CLA](https://go-review.googlesource.com/settings#Agreements) appropriate for
|
||||
you (I signed a personal one for all Google projects, but choose the right option for you.
|
||||
You can see all CLAs you've signed at [cla.developers.google.com/clas](https://cla.developers.google.com/clas)).
|
||||
|
||||
AND BAM. You're good (to go)! But where to contribute?
|
||||
|
||||
### Contributing
|
||||
|
||||
In the workshop, they sent us into the `scratch` repository, which is a safe place to
|
||||
fool around in order to master the workflow:
|
||||
|
||||
cd $(go env GOPATH)/src/golang.org/x
|
||||
git clone --depth 1 [[https://go.googlesource.com/scratch][go.googlesource.com/scratch]]
|
||||
|
||||
First stop is to `cd` in and run `go-contrib-init` to make sure you're ready to contribute:
|
||||
|
||||
go-contrib-init
|
||||
All good. Happy hacking!
|
||||
|
||||
From there, I made a folder named after my GitHub account, did a `git add -u`
|
||||
then took `git change` for a spin. It has a hash that keeps track of your work,
|
||||
which is the one line you shouldn't touch. Other than that, it feels just like
|
||||
`git commit`. Once I got the commit message matching the format of
|
||||
`package: description` (description begins with a lowercase), I used
|
||||
`git mail` to send it over to Gerrit.
|
||||
|
||||
Two good notes to take at this point: `git change` also works like `git commit --amend`, so
|
||||
if you need to update your patch you can `add` then `change` and it will all
|
||||
link to the same patch. Secondly, you can always review your patch from your
|
||||
[personal Gerrit dashboard](https://go-review.googlesource.com/dashboard/).
|
||||
|
||||
After a few back and forths, I officially had a contribute to Go! And if Jaana
|
||||
is right, it might be the first with emojis ✌️.
|
||||
|
||||
.image contributor-workshop/image15.png
|
||||
.image contributor-workshop/image23.png
|
||||
|
||||
### Contributing, For Real
|
||||
|
||||
The scratch repo is fun and all, but there's a ton of ways to get into the
|
||||
depths of Go's packages and give back. It's at this point where I cruised
|
||||
around the many packages available to see what was available and interesting to
|
||||
me. And by "cruised around" I mean attempted to find a list of packages, then
|
||||
went to my source code to see what's around under the `go/src/` folder:
|
||||
|
||||
.image contributor-workshop/image22.png
|
||||
|
||||
I decided to see what I can do in the `regexp` package, maybe out of love and
|
||||
fear of regex. Here's where I switched to the
|
||||
[website's view of the package](https://godoc.org/regexp) (it's good to know
|
||||
that each standard package can be found at https://godoc.org/$PACKAGENAME). In
|
||||
there I noticed that `QuoteMeta` was missing the same level of detailed examples
|
||||
other functions have (and I could use the practice using Gerrit).
|
||||
|
||||
.image contributor-workshop/image1.png
|
||||
|
||||
I started looking at `go/src/regexp` to try to find where to add examples and I
|
||||
got lost pretty quickly. Lucky for me, [Francesc](https://twitter.com/francesc) was around that day. He walked
|
||||
me through how all examples are actually in-line tests in a `example_test.go`
|
||||
file. They follow the format of test cases followed by "Output" commented out
|
||||
and then the answers to the tests. For example:
|
||||
|
||||
func ExampleRegexp_FindString() {
|
||||
re := regexp.MustCompile("fo.?")
|
||||
fmt.Printf("%q\n", re.FindString("seafood"))
|
||||
fmt.Printf("%q\n", re.FindString("meat"))
|
||||
// Output:
|
||||
// "foo"
|
||||
// ""
|
||||
}
|
||||
|
||||
Kind of cool, right?? I followed Francesc's lead and added a function
|
||||
`ExampleQuoteMeta` and added a few I thought would be helpful. From there it's
|
||||
a `git change` and `git mail` to Gerrit!
|
||||
|
||||
I have to say that Steve Francia challenged me to "find something that isn't an
|
||||
open issue and fix it," so I included some documentation changes for QuoteMeta
|
||||
in my patch. It's going to be open for a bit longer given the additional scope,
|
||||
but I think it's worth it on this one.
|
||||
|
||||
I can hear your question already: how did I verify it worked? Well it wasn't
|
||||
easy to be honest. Running `go test example_test.go -run QuoteMeta -v` won't do
|
||||
it since we're working outside of our $GOPATH. I struggled to figure it out
|
||||
until [Kale Blakenship wrote this awesome post on testing in Go](https://medium.com/@vCabbage/go-testing-standard-library-changes-1e9cbed11339).
|
||||
Bookmark this one for later.
|
||||
|
||||
You can see my completed [contribution here](https://go-review.googlesource.com/c/49130/). What I also hope you see is
|
||||
how simple it is to get into the flow of contributing. If you're like me,
|
||||
you'll be good at finding a small typo or missing example in the docs to start to
|
||||
get used to the `git codereview` workflow. After that, you'll be ready to find
|
||||
an open issue, ideally one [tagged for an upcoming release](https://github.com/golang/go/milestones), and give it a go. No matter
|
||||
what you choose to do, definitely go forth and do it. The Go team proved to me
|
||||
just how much they care about helping us all contribute back. I can't wait for
|
||||
my next `git mail`.
|
||||
|
||||
## My Mentorship Experience
|
||||
|
||||
by [Dmitri](https://twitter.com/dmitshur)
|
||||
|
||||
I was looking forward to participating in the Contribution Workshop event as a
|
||||
mentor. I had high expectations for the event, and thought it was a great idea
|
||||
before it started.
|
||||
|
||||
I made my first contribution to Go on May 10th, 2014. I remember it was about
|
||||
four months from the moment I wanted to contribute, until that day, when I
|
||||
actually sent my first CL. It took that long to build up the courage and fully
|
||||
commit to figuring out the process. I was an experienced software engineer at
|
||||
the time. Despite that, the Go contribution process felt alien—being unlike all
|
||||
other processes I was already familiar with—and therefore seemed intimidating.
|
||||
It was well documented though, so I knew it would be just a matter of finding
|
||||
the time, sitting down, and doing it. The "unknown" factor kept me from giving
|
||||
it a shot.
|
||||
|
||||
After a few months passed, I thought "enough is enough," and decided to
|
||||
dedicate an entire day of an upcoming weekend to figuring out the process. I
|
||||
set aside all of Saturday for doing one thing: sending my first CL to Go. I
|
||||
opened up [the Contribution Guide](https://golang.org/doc/contribute.html)
|
||||
and started following all the steps, from the very top. Within an hour, I was
|
||||
done. I had send my first CL. I was both in awe and shock. In awe, because I
|
||||
had finally sent a contribution to Go, and it was accepted! In shock, because,
|
||||
why did I wait so long to finally do this? Following the steps in
|
||||
[the Contribution Guide](https://golang.org/doc/contribute.html) was very
|
||||
easy, and the entire process went completely smoothly. If only someone had told
|
||||
me that I'd be done within an hour and nothing would go wrong, I would've done
|
||||
it much sooner!
|
||||
|
||||
Which brings me to this event and why I thought it was such a good idea. For
|
||||
anyone who ever wanted to contribute to Go, but felt daunted by the unfamiliar
|
||||
and seemingly lengthy process (like I was during those four months), this was
|
||||
their chance! Not only is it easy to commit to figuring it out by attending the
|
||||
event, but also the Go team and helpful volunteer mentors would be there to
|
||||
help you along the way.
|
||||
|
||||
Despite the already high expectations I had for the event, my expectations were
|
||||
exceeded. For one, the Go team had prepared really well and invested a lot in
|
||||
making the event that much more enjoyable for everyone. There was a very fun
|
||||
presentation that went over all the contributing steps quickly. There was a
|
||||
dashboard made for the event, where everyone's successfully completed steps
|
||||
were rewarded with points towards a global score. That made it into a very
|
||||
collaborative and social event! Finally, and most importantly, they were Go
|
||||
team members like Brad Fitzpatrick behind the scenes, helping review CLs
|
||||
promptly! That meant the CLs that were submitted received reviews quickly, with
|
||||
actionable next steps, so everyone could move forward and learn more.
|
||||
|
||||
I originally anticipated the event to be somewhat dull, in that the
|
||||
contribution steps are extremely simple to follow. However, I found that wasn't
|
||||
always the case, and I was able to use my expertise in Go to help out people
|
||||
who got stuck in various unexpected places. It turns out, the real world is
|
||||
filled with edge cases. For instance, someone had two git emails, one personal
|
||||
and another for work. There was a delay with signing the CLA for the work
|
||||
email, so they tried to use their personal email instead. That meant each
|
||||
commit had to be amended to use the right email, something the tools didn't
|
||||
take into account. (Luckily, there is a troubleshooting section in the
|
||||
contribution guide covering this exact issue!) There were other subtle mistakes
|
||||
or environment misconfiguration that some people ran into, because having more
|
||||
than one Go installation was a bit unusual. Sometimes, the GOROOT environment
|
||||
variable had to be explicitly set, temporarily, to get godoc to show changes in
|
||||
the right standard library (I was tongue-in-cheek looking over my shoulder to
|
||||
check for Dave Cheney as I uttered those words).
|
||||
|
||||
Overall, I oversaw a few new gophers make their first Go contributions. They
|
||||
sent the CLs, responded to review feedback, made edits, iterated until everyone
|
||||
was happy, and eventually saw their first Go contributions get merged to
|
||||
master! It was very rewarding to see the happiness on their faces, because the
|
||||
joy of making one's first contribution is something I can relate to myself. It
|
||||
was also great to be able to help them out, and explain tricky situations that
|
||||
they sometimes found themselves. From what I can tell, many happy gophers
|
||||
walked away from the event, myself included!
|
||||
|
||||
## Photos from the event
|
||||
|
||||
.image contributor-workshop/image2.jpg
|
||||
.image contributor-workshop/image4.jpg
|
||||
.image contributor-workshop/image5.jpg
|
||||
.image contributor-workshop/image8.jpg
|
||||
.image contributor-workshop/image14.jpg
|
||||
.image contributor-workshop/image18.jpg
|
||||
.image contributor-workshop/image20.jpg
|
||||
.image contributor-workshop/image21.jpg
|
||||
|
||||
Photos by Sameer Ajmani & Steve Francia
|
Двоичные данные
_content/contributor-workshop/image1.png
До Ширина: | Высота: | Размер: 170 KiB |
Двоичные данные
_content/contributor-workshop/image10.png
До Ширина: | Высота: | Размер: 33 KiB |
Двоичные данные
_content/contributor-workshop/image11.png
До Ширина: | Высота: | Размер: 306 KiB |
Двоичные данные
_content/contributor-workshop/image12.png
До Ширина: | Высота: | Размер: 39 KiB |
Двоичные данные
_content/contributor-workshop/image13.png
До Ширина: | Высота: | Размер: 46 KiB |
Двоичные данные
_content/contributor-workshop/image14.jpg
До Ширина: | Высота: | Размер: 327 KiB |
Двоичные данные
_content/contributor-workshop/image15.png
До Ширина: | Высота: | Размер: 57 KiB |
Двоичные данные
_content/contributor-workshop/image16.png
До Ширина: | Высота: | Размер: 117 KiB |
Двоичные данные
_content/contributor-workshop/image17.png
До Ширина: | Высота: | Размер: 369 KiB |