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>
This commit is contained in:
Russ Cox 2021-05-25 22:28:19 -04:00
Родитель da446da101
Коммит 9e547e58b9
789 изменённых файлов: 3 добавлений и 65269 удалений

Просмотреть файл

@ -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.

Просмотреть файл

@ -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 didnt 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 Gos 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).
Gos 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 Foundations 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 Gos success isnt just about the language.
Its 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 were 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 peoples 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.
Lets 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.
Its been a tough year, but
weve 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 Gos 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 everyones 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).
(Well 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 weve 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
Were also incredibly excited about whats in store for Gos 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 Youre 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 its 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 havent 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,
well be ready to make the VSCode Go extension use `gopls` by default,
for an excellent module experience out of the box,
and well 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.
Weve 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).
Were 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 everyones 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, weve 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 Gos 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 Gos
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.
Gos 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 projects 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 dont
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 Gos 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 were 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.)
Its 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.
Were 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 weve 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.
Were also exploring some further additions to the type system to make
generic programming easier.
A lot has happened in a year; its been both thrilling and satisfying.
We hope that this coming year will be even more fruitful than the last.
_If youve 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 weve 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.
Weve also added new ports, to Android on 32-bit x86, Linux on 64-bit MIPS,
and Linux on IBM z Systems.
And weve 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.5s 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 heres 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 [Gos 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, were including an updated chart. In this relative scale of
popularity, what was 100 four years ago is now a mere 17. Gos 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 arent 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.
## Gos 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
## Gos 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 heres 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 Overflows 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 arent using Go want to.
In [ActiveStates 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.
[JetBrainss 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 [HackerRanks 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
Its hard to believe that its only been five years since
the first Go conferences and Go meetups.
Weve 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, weve 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 communitys 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 Engines 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.
Lets 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, youll 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
##
Googles 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, were thrilled to announce that Go will be next.
Its marked as an experimental App Engine feature for now,
because its early days, but both the App Engine and Go teams are very
excited about this milestone.
By early days, we mean that its 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, youll be able to write web apps,
learn about the APIs (and the language, if its new to you),
and run your web app locally.
Once full deployment is enabled, itll be easy to push your app to Googles 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 dont 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 SDKs “dev app server” means you dont even need to
run the compiler yourself;
everything is delightfully automatic.
What youll 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 dont 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, its 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/).
Weve 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.
Wed like to offer our thanks for all the help and enthusiasm we received
from Googles 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&current=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 Gos 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 groups 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
Googles 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 Googles 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 weve 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 individuals 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

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше