Resolve conflicts

This commit is contained in:
unknown 2019-09-09 20:05:26 +02:00
commit a10f0a358a
175 changed files with 4039 additions and 1292 deletions

3
.gitattributes vendored Normal file
View File

@ -0,0 +1,3 @@
public/* linguist-generated=true
vendor/* linguist-vendored=true

2
.gitignore vendored
View File

@ -1 +1,3 @@
*.pyc
.idea
.vscode

View File

@ -15,4 +15,4 @@ script:
- tools/build
env:
- VERBOSE=1
- VERBOSE=1 TESTING=1

View File

@ -2,9 +2,11 @@
Thanks for your interest in contributing to Go by Example!
* If you see a typo or would like to suggest another small change, editing the
.go or .sh source file should be sufficient for the PR. I can rebuild the
HTML when I review the change.
* When sending a PR that affects the displayed contents of the site, run
`tools/build` locally and include the generated HTML in the PR. If you
only want to submit a simple typo suggestion (for example, through the
Github website), feel free to send a PR anyway - we'll regenerate the
HTML and merge with your commit.
* We're open to adding more examples to the site. They should be on things
used by many programmers and only require the standard library. If you're

View File

@ -46,6 +46,7 @@ String Functions
String Formatting
Regular Expressions
JSON
XML
Time
Epoch
Time Formatting / Parsing
@ -58,6 +59,8 @@ Reading Files
Writing Files
Line Filters
File Paths
Directories
Temporary Files and Directories
Command-Line Arguments
Command-Line Flags
Command-Line Subcommands

View File

@ -7,9 +7,11 @@
package main
import "fmt"
import "time"
import "sync/atomic"
import (
"fmt"
"sync"
"sync/atomic"
)
func main() {
@ -17,33 +19,34 @@ func main() {
// (always-positive) counter.
var ops uint64
// To simulate concurrent updates, we'll start 50
// goroutines that each increment the counter about
// once a millisecond.
// A WaitGroup will help us wait for all goroutines
// to finish their work.
var wg sync.WaitGroup
// We'll start 50 goroutines that each increment the
// counter exactly 1000 times.
for i := 0; i < 50; i++ {
wg.Add(1)
go func() {
for {
for c := 0; c < 1000; c++ {
// To atomically increment the counter we
// use `AddUint64`, giving it the memory
// address of our `ops` counter with the
// `&` syntax.
atomic.AddUint64(&ops, 1)
// Wait a bit between increments.
time.Sleep(time.Millisecond)
}
wg.Done()
}()
}
// Wait a second to allow some ops to accumulate.
time.Sleep(time.Second)
// Wait until all the goroutines are done.
wg.Wait()
// In order to safely use the counter while it's still
// being updated by other goroutines, we extract a
// copy of the current value into `opsFinal` via
// `LoadUint64`. As above we need to give this
// function the memory address `&ops` from which to
// fetch the value.
opsFinal := atomic.LoadUint64(&ops)
fmt.Println("ops:", opsFinal)
// It's safe to access `ops` now because we know
// no other goroutine is writing to it. Reading
// atomics safely while they are being updated is
// also possible, using functions like
// `atomic.LoadUint64`.
fmt.Println("ops:", ops)
}

View File

@ -1,2 +1,2 @@
a4190094ea0405b5f2733101beb97939a1d43aee
KDr9EMMPMgi
8ebec0be3b167021c96b8b497d0e8c0a2ea99385
F2pJfduyQiA

View File

@ -1,7 +1,11 @@
# Running the program shows that we executed about
# 40,000 operations.
# We expect to get exactly 50,000 operations. Had we
# used the non-atomic `ops++` to increment the counter,
# we'd likely get a different number, changing between
# runs, because the goroutines would interfere with
# each other. Moreover, we'd get data race failures
# when running with the `-race` flag.
$ go run atomic-counters.go
ops: 41419
ops: 50000
# Next we'll look at mutexes, another tool for managing
# state.

View File

@ -6,8 +6,10 @@ package main
// This syntax imports the `encoding/base64` package with
// the `b64` name instead of the default `base64`. It'll
// save us some space below.
import b64 "encoding/base64"
import "fmt"
import (
b64 "encoding/base64"
"fmt"
)
func main() {

View File

@ -1,2 +1,2 @@
c20da14820b656c867790f2e99bc37140babca8c
y_QTcqdkvZh
e0148b9b4acb01e849b8f678cba03f549d250c44
V3oV1bvh94k

View File

@ -6,8 +6,10 @@
package main
import "fmt"
import "time"
import (
"fmt"
"time"
)
// This is the function we'll run in a goroutine. The
// `done` channel will be used to notify another

View File

@ -1,2 +1,2 @@
eb022977181884c2ab0f2b69e50311769e67a509
8lmP8beav0p
0d5a9de912e2a4a18943e082e2f8107cb75d0ce4
fe9If6OhYMk

View File

@ -18,8 +18,10 @@
package main
import "strings"
import "fmt"
import (
"fmt"
"strings"
)
// Index returns the first index of the target string `t`, or
// -1 if no match is found.

View File

@ -1,2 +1,2 @@
d961fc0e0074aed46cfd1516efdadea78781af56
BJB_npWH516
28456737ea996664bdaeb8e1e821d95697d00646
8hI6oPNEfyh

View File

@ -5,8 +5,10 @@
package main
import "os"
import "fmt"
import (
"fmt"
"os"
)
func main() {

View File

@ -1,2 +1,2 @@
41c970a1ef29ad2a05307e6c783ff52ab80eaccd
6pFdjf800jj
9c80d495201148bbeb0fd0a5a2ce1735aeb34b60
myJy_-H8Fo_Q

View File

@ -8,8 +8,10 @@ package main
// Go provides a `flag` package supporting basic
// command-line flag parsing. We'll use this package to
// implement our example command-line program.
import "flag"
import "fmt"
import (
"flag"
"fmt"
)
func main() {

View File

@ -1,2 +1,2 @@
e2ba0461c090789168c712cc7ed0f66aab09a8c8
klFR5DitrCy
ab08bf890dcd87b807956b5bee441d59efe458e3
lPaZodnG9TF

View File

@ -3,8 +3,10 @@
package main
import "fmt"
import "math"
import (
"fmt"
"math"
)
// `const` declares a constant value.
const s string = "constant"

View File

@ -1,2 +1,2 @@
2f2ec3a5ff4eef280199da1908eed261346fb40e
VhP0f8moZd3
7cc09460e8dc6fffd0ba811679f92a85eb51e927
gmjHSglwLic

View File

@ -5,8 +5,10 @@
package main
import "fmt"
import "os"
import (
"fmt"
"os"
)
// Suppose we wanted to create a file, write to it,
// and then close when we're done. Here's how we could
@ -40,5 +42,11 @@ func writeFile(f *os.File) {
func closeFile(f *os.File) {
fmt.Println("closing")
f.Close()
err := f.Close()
// It's important to check for errors when closing a
// file, even in a deferred function.
if err != nil {
fmt.Fprintf(os.Stderr, "error: %v\n", err)
os.Exit(1)
}
}

View File

@ -1,2 +1,2 @@
570699fc50a1d39e9d0ad6a4461aef3248b080e1
xPbQ5SGkH2O
4fc23579a9bd5d8512884902394f4dce51eb7d60
QJJ2R6kv6K5

View File

@ -0,0 +1,95 @@
// Go has several useful functions for working with
// *directories* in the file system.
package main
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
)
func check(e error) {
if e != nil {
panic(e)
}
}
func main() {
// Create a new sub-directory in the current working
// directory.
err := os.Mkdir("subdir", 0755)
check(err)
// When creating temporary directories, it's good
// practice to `defer` their removal. `os.RemoveAll`
// will delete a whole directory tree (similarly to
// `rm -rf`).
defer os.RemoveAll("subdir")
// Helper function to create a new empty file.
createEmptyFile := func(name string) {
d := []byte("")
check(ioutil.WriteFile(name, d, 0644))
}
createEmptyFile("subdir/file1")
// We can create a hierarchy of directories, including
// parents with `MkdirAll`. This is similar to the
// command-line `mkdir -p`.
err = os.MkdirAll("subdir/parent/child", 0755)
check(err)
createEmptyFile("subdir/parent/file2")
createEmptyFile("subdir/parent/file3")
createEmptyFile("subdir/parent/child/file4")
// `ReadDir` lists directory contents, returning a
// slice of `os.FileInfo` objects.
c, err := ioutil.ReadDir("subdir/parent")
check(err)
fmt.Println("Listing subdir/parent")
for _, entry := range c {
fmt.Println(" ", entry.Name(), entry.IsDir())
}
// `Chdir` lets us change the current working directory,
// similarly to `cd`.
err = os.Chdir("subdir/parent/child")
check(err)
// Now we'll see the contents of `subdir/parent/child`
// when listing the *current* directory.
c, err = ioutil.ReadDir(".")
check(err)
fmt.Println("Listing subdir/parent/child")
for _, entry := range c {
fmt.Println(" ", entry.Name(), entry.IsDir())
}
// `cd` back to where we started.
err = os.Chdir("../../..")
check(err)
// We can also visit a directory *recursively*,
// including all its sub-directories. `Walk` accepts
// a callback function to handle every file or
// directory visited.
fmt.Println("Visiting subdir")
err = filepath.Walk("subdir", visit)
}
// `visit` is called for every file or directory found
// recursively by `filepath.Walk`.
func visit(p string, info os.FileInfo, err error) error {
if err != nil {
return err
}
fmt.Println(" ", p, info.IsDir())
return nil
}

View File

@ -0,0 +1,2 @@
83f67db91816b4544072d0a4d099111a21c60723
-7kWq0PmATF

View File

@ -0,0 +1,15 @@
$ go run directories.go
Listing subdir/parent
child true
file2 false
file3 false
Listing subdir/parent/child
file4 false
Visiting subdir
subdir true
subdir/file1 false
subdir/parent true
subdir/parent/child true
subdir/parent/child/file4 false
subdir/parent/file2 false
subdir/parent/file3 false

View File

@ -5,9 +5,11 @@
package main
import "os"
import "strings"
import "fmt"
import (
"fmt"
"os"
"strings"
)
func main() {

View File

@ -1,2 +1,2 @@
4d0832c5a1ddd4e95474791e8802c15452358214
CZJ4R_uu6Uu
db2e203da519a22943753295e9cc27d89e4347b0
bKuCOOD16KH

View File

@ -5,8 +5,10 @@
package main
import "fmt"
import "time"
import (
"fmt"
"time"
)
func main() {

View File

@ -1,2 +1,2 @@
61a498229c8878a97d729cfdd215e5f3960f87ac
eN1Qv2ATB-C
184c8f3e94dd28176be81956115ac417e33513a6
3uYNHHRplmQ

View File

@ -9,8 +9,10 @@
package main
import "errors"
import "fmt"
import (
"errors"
"fmt"
)
// By convention, errors are the last return value and
// have type `error`, a built-in interface.

View File

@ -1,2 +1,2 @@
210ba0f8196006c0380acaec01655816848ef168
mP_ZR1qjUvA
ed58ad3162d93c723d3efe72529a61ce7041fe13
vrwN32gxaYx

View File

@ -10,9 +10,11 @@
package main
import "syscall"
import "os"
import "os/exec"
import (
"os"
"os/exec"
"syscall"
)
func main() {

View File

@ -1,2 +1,2 @@
b527bbb76a42dd4bae541b73a7377b7e83e79905
bf11ADw-2Ho
e6b4830d4264f307506b54726ec79b25a0363874
ahZjpJaZz44

View File

@ -3,8 +3,10 @@
package main
import "fmt"
import "os"
import (
"fmt"
"os"
)
func main() {

View File

@ -1,2 +1,2 @@
dc0bb3eaafa045d6aa05e88aff39322a1ccf822e
vDaM0-MGJ_k
2316e6c8e364e2066c6bd350dc9b0b2af85b63fe
OX997ykuOGx

View File

@ -17,7 +17,7 @@ func hello(w http.ResponseWriter, req *http.Request) {
// Functions serving as handlers take a
// `http.ResponseWriter` and a `http.Request` as
// arguments. The response writer is used to fill in the
// HTTP response. Here out simple response is just
// HTTP response. Here our simple response is just
// "hello\n".
fmt.Fprintf(w, "hello\n")
}

View File

@ -1,2 +1,2 @@
ac2909e69be30862bd9f18db954d9ee10f57ec6a
8GBAW6yNcbn
a4e8d30b7a6f3a6abd96b916d81ce5930bad94f9
lNuS9ysZmxH

View File

@ -3,8 +3,10 @@
package main
import "fmt"
import "math"
import (
"fmt"
"math"
)
// Here's a basic interface for geometric shapes.
type geometry interface {

View File

@ -1,2 +1,2 @@
3547b935d1e0322c0fb696726c27cae53a275e0a
0EwsqIn3TTi
aac1328f5a04568272b82753ff0762b9eacff4fc
hXTlbUAGcvn

View File

@ -4,9 +4,11 @@
package main
import "encoding/json"
import "fmt"
import "os"
import (
"encoding/json"
"fmt"
"os"
)
// We'll use these two structs to demonstrate encoding and
// decoding of custom types below.
@ -14,6 +16,9 @@ type response1 struct {
Page int
Fruits []string
}
// Only exported fields will be encoded/decoded in JSON.
// Fields must start with capital letters to be exported.
type response2 struct {
Page int `json:"page"`
Fruits []string `json:"fruits"`

View File

@ -1,2 +1,2 @@
d4dc2281f64061f077d8f1e9687538f41a339b25
xC6SHbzGBZC
c751bc7223b8bc615f82fe7643ab98ce2b80240f
ROikmz5tRhZ

View File

@ -5,8 +5,10 @@ package main
// The built-in package `strconv` provides the number
// parsing.
import "strconv"
import "fmt"
import (
"fmt"
"strconv"
)
func main() {

View File

@ -1,2 +1,2 @@
0d2155e9863a73c098d44637e92403d7f5e8e965
NZh4LjhguvN
0191c7e43706640207c403ba92dd2272d66fc868
t2q4KnWWTAw

View File

@ -4,9 +4,11 @@
package main
import "time"
import "fmt"
import "math/rand"
import (
"fmt"
"math/rand"
"time"
)
func main() {

View File

@ -1,2 +1,2 @@
8e97de760147b061dd09939db294c892211b6b80
jiJaIjxL2sP
9374869a809d28ea784a9e1181b4aa1988018776
DVHO7SjJZnp

View File

@ -6,8 +6,10 @@
package main
import "time"
import "fmt"
import (
"fmt"
"time"
)
func main() {

View File

@ -1,2 +1,2 @@
edad78bf3b36ddc9bec30b344b8a72be4de90f3b
l4uDE-RCDpa
357d83df3e48675eb1e135188cb9f07448c1f146
AJ-MJephNib

View File

@ -4,9 +4,11 @@
package main
import "bytes"
import "fmt"
import "regexp"
import (
"bytes"
"fmt"
"regexp"
)
func main() {

View File

@ -1,2 +1,2 @@
7cde6b9af5cf6c47606001dd54eee468a6c61dbb
qR5gn2l0AGa
de24265897edf1d3913e3b87f70757284a66ecea
urHlUNDVenk

View File

@ -4,8 +4,10 @@
package main
import "time"
import "fmt"
import (
"fmt"
"time"
)
func main() {

View File

@ -1,2 +1,2 @@
8d743edffd7de6bf7bccdf4437f45672b6adc75e
ZdSOPe1Gj13
6e1125087bc036ebd905452300575f160d683918
yF-xgN7Xf9P

View File

@ -9,8 +9,10 @@ package main
// Go implements several hash functions in various
// `crypto/*` packages.
import "crypto/sha1"
import "fmt"
import (
"crypto/sha1"
"fmt"
)
func main() {
s := "sha1 this string"

View File

@ -1,2 +1,2 @@
6a896270e34f2696b881a8fa7e68bfff57dee51f
1oT-5GBUkLr
4cda643ba233014fe6b30966c37d4d0fcd4edbe8
oqcrTfY4Ykd

View File

@ -7,10 +7,12 @@
package main
import "fmt"
import "os"
import "os/signal"
import "syscall"
import (
"fmt"
"os"
"os/signal"
"syscall"
)
func main() {

View File

@ -1,2 +1,2 @@
9720d747e3ab2893df508a70cbb341c90fdd7ca1
9koJAW1raI5
1e43c6f63f1d57e1a52c89f52d35b68757e9676b
_6oj-T3Gko2

View File

@ -6,8 +6,10 @@
package main
import "sort"
import "fmt"
import (
"fmt"
"sort"
)
// In order to sort by a custom function in Go, we need a
// corresponding type. Here we've created a `byLength`

View File

@ -1,2 +1,2 @@
6a04058b564d5741815e523f97f240ee6563cb15
y3kuCwIFRYK
f7d0b7840dd12601fb86946f9dc4c38fb1c0501f
Jtxf94x94Hx

View File

@ -4,8 +4,10 @@
package main
import "fmt"
import "sort"
import (
"fmt"
"sort"
)
func main() {

View File

@ -1,2 +1,2 @@
4e576421f2bdbd11847c367d223bd30d0e301990
e6hp3Rn-oH6
e11e944d34b21e75ce4f7c91026d4200ce592dc5
tAWAkRlBJNX

View File

@ -7,9 +7,11 @@
package main
import "fmt"
import "io/ioutil"
import "os/exec"
import (
"fmt"
"io/ioutil"
"os/exec"
)
func main() {

View File

@ -1,2 +1,2 @@
0b676b93e41ac5434003c194bc038d5f3ce76bc8
6HRWVK5gPYU
cc68e4290f10209ad2fa8db74fdfaea7fdb44d5c
QS_Nkoe8VLG

View File

@ -4,8 +4,10 @@
package main
import "fmt"
import "os"
import (
"fmt"
"os"
)
type point struct {
x, y int

View File

@ -1,2 +1,2 @@
5f39ae6d8f26d59a688a9a9d7d13a5c1d0f7a08b
CkBQ3CFpHQ9
12b245c576b43537c092a5b84995ebca8ce78a57
vmYSdxfUcRh

View File

@ -4,8 +4,10 @@
package main
import s "strings"
import "fmt"
import (
"fmt"
s "strings"
)
// We alias `fmt.Println` to a shorter name as we'll use
// it a lot below.

View File

@ -1,2 +1,2 @@
17aa523bbd606fa0b624fae44b89812d46330755
Vn4D3y4_711
bf39c7540bd78eba38eb5a9047a9d0ffc7235f85
xoRUhG86wsF

View File

@ -12,6 +12,15 @@ type person struct {
age int
}
// NewPerson constructs a new person struct with the given name
func NewPerson(name string) *person {
// You can safely return a pointer to local variable
// as a local variable will survive the scope of the function.
p := person{name: name}
p.age = 42
return &p
}
func main() {
// This syntax creates a new struct.
@ -26,6 +35,9 @@ func main() {
// An `&` prefix yields a pointer to the struct.
fmt.Println(&person{name: "Ann", age: 40})
// It's idiomatic to encapsulate new struct creation in constructor functions
fmt.Println(NewPerson("Jon"))
// Access struct fields with a dot.
s := person{name: "Sean", age: 50}
fmt.Println(s.name)

View File

@ -1,2 +1,2 @@
49cad39331ee5e9fb8d8dad99d3aff7f18a4e6d0
XMZpGsF4sWM
c5caaf1eefaf084d688afb70d2ee5884a4983182
00Yiw6xuICq

View File

@ -6,3 +6,4 @@ $ go run structs.go
Sean
50
51
&{Jon 42}

View File

@ -3,8 +3,10 @@
package main
import "fmt"
import "time"
import (
"fmt"
"time"
)
func main() {

View File

@ -1,2 +1,2 @@
b47004b3e3b6d787ea98642dc5b955df57cd2bcd
TJ4Az0KuLfL
2486fc553301cdeac9a26f3d0b3aed4143d9f4f0
ZcDzdx3nYQn

View File

@ -0,0 +1,65 @@
// Throughout program execution, we often want to create
// data that isn't needed after the program exits.
// *Temporary files and directories* are useful for this
// purpose since they don't pollute the file system over
// time.
package main
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
)
func check(e error) {
if e != nil {
panic(e)
}
}
func main() {
// The easiest way to create a temporary file is by
// calling `ioutil.TempFile`. It creates a file *and*
// opens it for reading and writing. We provide `""`
// as the first argument, so `ioutil.TempFile` will
// create the file in the default location for our OS.
f, err := ioutil.TempFile("", "sample")
check(err)
// Display the name of the temporary file. On
// Unix-based OSes the directory will likely be `/tmp`.
// The file name starts with the prefix given as the
// second argument to `ioutil.TempFile` and the rest
// is chosen automatically to ensure that concurrent
// calls will always create different file names.
fmt.Println("Temp file name:", f.Name())
// Clean up the file after we're done. The OS is
// likely to clean up temporary files by itself after
// some time, but it's good practice to do this
// explicitly.
defer os.Remove(f.Name())
// We can write some data to the file.
_, err = f.Write([]byte{1, 2, 3, 4})
check(err)
// If we intend to write many temporary files, we may
// prefer to create a temporary *directory*.
// `ioutil.TempDir`'s arguments are the same as
// `TempFile`'s, but it returns a directory *name*
// rather than an open file.
dname, err := ioutil.TempDir("", "sampledir")
fmt.Println("Temp dir name:", dname)
defer os.RemoveAll(dname)
// Now we can synthesize temporary file names by
// prefixing them with our temporary directory.
fname := filepath.Join(dname, "file1")
err = ioutil.WriteFile(fname, []byte{1, 2}, 0666)
check(err)
}

View File

@ -0,0 +1,2 @@
5f7d0c43988d7dce235adb06ec02f4d2026b7f83
pxE20wGTFjv

View File

@ -0,0 +1,3 @@
$ go run temporary-files-and-directories.go
Temp file name: /tmp/sample610887201
Temp dir name: /tmp/sampledir898854668

View File

@ -6,8 +6,10 @@
package main
import "time"
import "fmt"
import (
"fmt"
"time"
)
func main() {
@ -16,10 +18,17 @@ func main() {
// `range` builtin on the channel to iterate over
// the values as they arrive every 500ms.
ticker := time.NewTicker(500 * time.Millisecond)
done := make(chan bool)
go func() {
for t := range ticker.C {
for {
select {
case <-done:
return
case t := <-ticker.C:
fmt.Println("Tick at", t)
}
}
}()
// Tickers can be stopped like timers. Once a ticker
@ -27,5 +36,6 @@ func main() {
// channel. We'll stop ours after 1600ms.
time.Sleep(1600 * time.Millisecond)
ticker.Stop()
done <- true
fmt.Println("Ticker stopped")
}

View File

@ -1,2 +1,2 @@
7dc6447323f493f72aa70952bf3e3f2c6156f82f
Rgc_UDvHv6a
4a42333d14f902e890902343c7bd9b9c735fd8ad
n1q1sSGEvmv

View File

@ -3,8 +3,10 @@
package main
import "fmt"
import "time"
import (
"fmt"
"time"
)
func main() {
p := fmt.Println

View File

@ -1,2 +1,2 @@
1f9962260f5c92efe57db0b96099b3dd06c90333
nHAisH6amZG
9e3f17061fef280191e3e8518365e231e17a5d5a
1410R7Fcyx0

View File

@ -3,8 +3,10 @@
package main
import "fmt"
import "time"
import (
"fmt"
"time"
)
func main() {
p := fmt.Println

View File

@ -1,2 +1,2 @@
b6308f1fea7665e89a28f54aac6cb49b95685eb5
PZMCzzaJURJ
c47d853fa7527a652ce78b0285e452c6cd740050
u-7i_p8BHVt

View File

@ -5,14 +5,19 @@
package main
import "time"
import "fmt"
import (
"fmt"
"time"
)
func main() {
// For our example, suppose we're executing an external
// call that returns its result on a channel `c1`
// after 2s.
// after 2s. Note that the channel is buffered, so the
// send in the goroutine is nonblocking. This is a
// common pattern to prevent goroutine leaks in case the
// channel is never read.
c1 := make(chan string, 1)
go func() {
time.Sleep(2 * time.Second)

View File

@ -1,2 +1,2 @@
93343e1aacb14f818c87732914c29ba57afab245
MgcfA-xpJO9
b8d3e745539b24d3530ca21efcdc924f08769edb
TYJgoFjlTd6

View File

@ -3,9 +3,3 @@
$ go run timeouts.go
timeout 1
result 2
# Using this `select` timeout pattern requires
# communicating results over channels. This is a good
# idea in general because other important Go features are
# based on channels and `select`. We'll look at two
# examples of this next: timers and tickers.

View File

@ -6,8 +6,10 @@
package main
import "time"
import "fmt"
import (
"fmt"
"time"
)
func main() {

View File

@ -1,2 +1,2 @@
e10c601ab3b702dfcea728c1edb31673561484b5
pybl9hRvJq2
e8e501d6083bea786629ca5e485e8b18caab4815
pLnKEIesooU

View File

@ -3,9 +3,11 @@
package main
import "fmt"
import "net"
import "net/url"
import (
"fmt"
"net"
"net/url"
)
func main() {

View File

@ -1,2 +1,2 @@
b7a0813e9413bfcc956cc58b850f655dd129ebb7
AL79Lv-9CWo
babc12f5066652f4cb0151231c06f1037298ff28
M218D9Tldlr

View File

@ -3,8 +3,10 @@
package main
import "fmt"
import "time"
import (
"fmt"
"time"
)
// Here's the worker, of which we'll run several
// concurrent instances. These workers will receive

View File

@ -1,2 +1,2 @@
bc69c6602d438413dcb9ceac112299ee253e4575
yuHsGf712D1
9b30cdfc3f46d634c3b8671a7ae1551c133fb6e2
IiKZ-nj-nKY

69
examples/xml/xml.go Normal file
View File

@ -0,0 +1,69 @@
// Go offers built-in support for XML and XML-like
// formats with the `encoding.xml` package.
package main
import (
"encoding/xml"
"fmt"
)
// This type will be mapped to XML. Similarly to the
// JSON examples, field tags contain directives for the
// encoder and decoder. Here we use some special features
// of the XML package: the `XMLName` field name dictates
// the name of the XML element representing this struct;
// `id,attr` means that the `Id` field is an XML
// _attribute_ rather than a nested element.
type Plant struct {
XMLName xml.Name `xml:"plant"`
Id int `xml:"id,attr"`
Name string `xml:"name"`
Origin []string `xml:"origin"`
}
func (p Plant) String() string {
return fmt.Sprintf("Plant id=%v, name=%v, origin=%v",
p.Id, p.Name, p.Origin)
}
func main() {
coffee := &Plant{Id: 27, Name: "Coffee"}
coffee.Origin = []string{"Ethiopia", "Brazil"}
// Emit XML representing our plant; using
// `MarshalIndent` to produce a more
// human-readable output.
out, _ := xml.MarshalIndent(coffee, " ", " ")
fmt.Println(string(out))
// To add a generic XML header to the output, append
// it explicitly.
fmt.Println(xml.Header + string(out))
// Use `Unmarhshal` to parse a stream of bytes with XML
// into a data structure. If the XML is malformed or
// cannot be mapped onto Plant, a descriptive error
// will be returned.
var p Plant
if err := xml.Unmarshal(out, &p); err != nil {
panic(err)
}
fmt.Println(p)
tomato := &Plant{Id: 81, Name: "Tomato"}
tomato.Origin = []string{"Mexico", "California"}
// The `parent>child>plant` field tag tells the encoder
// to nest all `plant`s under `<parent><child>...`
type Nesting struct {
XMLName xml.Name `xml:"nesting"`
Plants []*Plant `xml:"parent>child>plant"`
}
nesting := &Nesting{}
nesting.Plants = []*Plant{coffee, tomato}
out, _ = xml.MarshalIndent(nesting, " ", " ")
fmt.Println(string(out))
}

2
examples/xml/xml.hash Normal file
View File

@ -0,0 +1,2 @@
18ada773098bca38778a58b438d6af70529f18b0
qd9Ii_3AW0s

29
examples/xml/xml.sh Normal file
View File

@ -0,0 +1,29 @@
$ go run xml.go
<plant id="27">
<name>Coffee</name>
<origin>Ethiopia</origin>
<origin>Brazil</origin>
</plant>
<?xml version="1.0" encoding="UTF-8"?>
<plant id="27">
<name>Coffee</name>
<origin>Ethiopia</origin>
<origin>Brazil</origin>
</plant>
Plant id=27, name=Coffee, origin=[Ethiopia Brazil]
<nesting>
<parent>
<child>
<plant id="27">
<name>Coffee</name>
<origin>Ethiopia</origin>
<origin>Brazil</origin>
</plant>
<plant id="81">
<name>Tomato</name>
<origin>Mexico</origin>
<origin>California</origin>
</plant>
</child>
</parent>
</nesting>

23
public/arrays generated
View File

@ -5,6 +5,20 @@
<title>Go by Example: Arrays</title>
<link rel=stylesheet href="site.css">
</head>
<script>
onkeydown = (e) => {
if (e.key == "ArrowLeft") {
window.location.href = 'switch';
}
if (e.key == "ArrowRight") {
window.location.href = 'slices';
}
}
</script>
<body>
<div class="example" id="arrays">
<h2><a href="./">Go by Example</a>: Arrays</h2>
@ -28,9 +42,7 @@ specific length.</p>
</td>
<td class="code leading">
<a href="http://play.golang.org/p/W7NwfDq8Vdw">
<img title="Run code" class="run" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAPCAYAAADtc08vAAAABGdBTUEAANbY1E9YMgAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJ1SURBVCjPY/j//z8DMu7o6GAAgpQgD9tLqcmJH4KDg14aaik/MtdXe2ZjY6OCrh6Fs2jRYmZ9Pd05M9uL/u9dPfU/CLS0dfxvKIz/X5Dg/z8pKdkGqwGpqakMUdExDHJSYqt37tjxf+qUSf9rc2P+79298/+RA3v+H1zV///o6r7/DrbWFQkJiQwxMTGoBjAxMTpKiQmuqMuP/f/xw/v/J0+f/W9tbvTfxVLn/8rJVf+v757z/96hRf8TQtxuCQmLMjk4OKAawMfDVWVvrvd85eTq/7tXTP6/e/XM/22lif9LCnL+b13Q/v/Kzln/L++c/X/7/Jb/VpYWuZFRUagGAAErEBtlxvi+vn944f9L26cDNcz6v21R9/8zm6aC2SBDbu+f/78kK+4/L79AO7oBYCAqxD/57JZp/y/tmPX/wrYZ/6+CbAayD6zs/78daBjIgPayFJAGG6wGAIFAcpjH/dv7F4ANABuya/b/Od3l/ye2V/+/tnv2/7ldxSANmrgMYGBhZg7fuagD7GyYIeeBrrqwdRrQgLn/l02sBGkwwWkAEAjV5EZ/vQV0LswAGAYZsLC3DKTBAJ8BzCkRni/uHFyIYcAtoNc6ypL/ANVIohigrKwMxqqqqgxMzKzM6VHeL+6iGQAKzDtAV5XlJv3n5uFLRTHgzZs3YPzz50+GwqJiPitD9Y8Pjy4BB+CNvfP+3wUmIpAhhckhr3X19LodHZ28UQxQU1MDYw0NDQYBAQEeoBOTK7JjP2xf3Pt/bkfB/4KkoDcKMmIL5OXlFerq6hhu3rzJgC8MwMDYxGSfm5vbVn9/f0cgVxAkpqioyFBfX49iAACbTAK+xT3CzgAAAABJRU5ErkJggg==" />
</a>
<a href="http://play.golang.org/p/W7NwfDq8Vdw"><img title="Run code" src="play.png" class="run" /></a><img title="Copy code" src="clipboard.png" class="copy" />
<div class="highlight"><pre><span class="kn">package</span> <span class="nx">main</span>
</pre></div>
@ -192,5 +204,10 @@ typical Go. We&rsquo;ll look at slices next.</p>
by <a href="https://markmcgranaghan.com">Mark McGranaghan</a> | <a href="https://github.com/mmcgrana/gobyexample/blob/master/examples/arrays">source</a> | <a href="https://github.com/mmcgrana/gobyexample#license">license</a>
</p>
</div>
<script>
var codeLines = [];
codeLines.push('');codeLines.push('package main\u000A');codeLines.push('import \"fmt\"\u000A');codeLines.push('func main() {\u000A');codeLines.push(' var a [5]int\u000A fmt.Println(\"emp:\", a)\u000A');codeLines.push(' a[4] = 100\u000A fmt.Println(\"set:\", a)\u000A fmt.Println(\"get:\", a[4])\u000A');codeLines.push(' fmt.Println(\"len:\", len(a))\u000A');codeLines.push(' b := [5]int{1, 2, 3, 4, 5}\u000A fmt.Println(\"dcl:\", b)\u000A');codeLines.push(' var twoD [2][3]int\u000A for i := 0; i \x3C 2; i++ {\u000A for j := 0; j \x3C 3; j++ {\u000A twoD[i][j] = i + j\u000A }\u000A }\u000A fmt.Println(\"2d: \", twoD)\u000A}\u000A');codeLines.push('');codeLines.push('');
</script>
<script src="site.js" async></script>
</body>
</html>

88
public/atomic-counters generated
View File

@ -5,6 +5,20 @@
<title>Go by Example: Atomic Counters</title>
<link rel=stylesheet href="site.css">
</head>
<script>
onkeydown = (e) => {
if (e.key == "ArrowLeft") {
window.location.href = 'rate-limiting';
}
if (e.key == "ArrowRight") {
window.location.href = 'mutexes';
}
}
</script>
<body>
<div class="example" id="atomic-counters">
<h2><a href="./">Go by Example</a>: Atomic Counters</h2>
@ -32,9 +46,7 @@ counters</em> accessed by multiple goroutines.</p>
</td>
<td class="code leading">
<a href="http://play.golang.org/p/KDr9EMMPMgi">
<img title="Run code" class="run" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAPCAYAAADtc08vAAAABGdBTUEAANbY1E9YMgAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJ1SURBVCjPY/j//z8DMu7o6GAAgpQgD9tLqcmJH4KDg14aaik/MtdXe2ZjY6OCrh6Fs2jRYmZ9Pd05M9uL/u9dPfU/CLS0dfxvKIz/X5Dg/z8pKdkGqwGpqakMUdExDHJSYqt37tjxf+qUSf9rc2P+79298/+RA3v+H1zV///o6r7/DrbWFQkJiQwxMTGoBjAxMTpKiQmuqMuP/f/xw/v/J0+f/W9tbvTfxVLn/8rJVf+v757z/96hRf8TQtxuCQmLMjk4OKAawMfDVWVvrvd85eTq/7tXTP6/e/XM/22lif9LCnL+b13Q/v/Kzln/L++c/X/7/Jb/VpYWuZFRUagGAAErEBtlxvi+vn944f9L26cDNcz6v21R9/8zm6aC2SBDbu+f/78kK+4/L79AO7oBYCAqxD/57JZp/y/tmPX/wrYZ/6+CbAayD6zs/78daBjIgPayFJAGG6wGAIFAcpjH/dv7F4ANABuya/b/Od3l/ye2V/+/tnv2/7ldxSANmrgMYGBhZg7fuagD7GyYIeeBrrqwdRrQgLn/l02sBGkwwWkAEAjV5EZ/vQV0LswAGAYZsLC3DKTBAJ8BzCkRni/uHFyIYcAtoNc6ypL/ANVIohigrKwMxqqqqgxMzKzM6VHeL+6iGQAKzDtAV5XlJv3n5uFLRTHgzZs3YPzz50+GwqJiPitD9Y8Pjy4BB+CNvfP+3wUmIpAhhckhr3X19LodHZ28UQxQU1MDYw0NDQYBAQEeoBOTK7JjP2xf3Pt/bkfB/4KkoDcKMmIL5OXlFerq6hhu3rzJgC8MwMDYxGSfm5vbVn9/f0cgVxAkpqioyFBfX49iAACbTAK+xT3CzgAAAABJRU5ErkJggg==" />
</a>
<a href="http://play.golang.org/p/F2pJfduyQiA"><img title="Run code" src="play.png" class="run" /></a><img title="Copy code" src="clipboard.png" class="copy" />
<div class="highlight"><pre><span class="kn">package</span> <span class="nx">main</span>
</pre></div>
@ -47,9 +59,11 @@ counters</em> accessed by multiple goroutines.</p>
</td>
<td class="code leading">
<div class="highlight"><pre><span class="kn">import</span> <span class="s">&quot;fmt&quot;</span>
<span class="kn">import</span> <span class="s">&quot;time&quot;</span>
<span class="kn">import</span> <span class="s">&quot;sync/atomic&quot;</span>
<div class="highlight"><pre><span class="kn">import</span> <span class="p">(</span>
<span class="s">&quot;fmt&quot;</span>
<span class="s">&quot;sync&quot;</span>
<span class="s">&quot;sync/atomic&quot;</span>
<span class="p">)</span>
</pre></div>
</td>
@ -83,16 +97,28 @@ counters</em> accessed by multiple goroutines.</p>
<tr>
<td class="docs">
<p>To simulate concurrent updates, we&rsquo;ll start 50
goroutines that each increment the counter about
once a millisecond.</p>
<p>A WaitGroup will help us wait for all goroutines
to finish their work.</p>
</td>
<td class="code leading">
<div class="highlight"><pre> <span class="kd">var</span> <span class="nx">wg</span> <span class="nx">sync</span><span class="p">.</span><span class="nx">WaitGroup</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
<p>We&rsquo;ll start 50 goroutines that each increment the
counter exactly 1000 times.</p>
</td>
<td class="code leading">
<div class="highlight"><pre> <span class="k">for</span> <span class="nx">i</span> <span class="o">:=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="p">&lt;</span> <span class="mi">50</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span> <span class="p">{</span>
<span class="k">go</span> <span class="kd">func</span><span class="p">()</span> <span class="p">{</span>
<span class="k">for</span> <span class="p">{</span>
<span class="nx">wg</span><span class="p">.</span><span class="nx">Add</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</pre></div>
</td>
@ -108,7 +134,8 @@ address of our <code>ops</code> counter with the
</td>
<td class="code leading">
<div class="highlight"><pre> <span class="nx">atomic</span><span class="p">.</span><span class="nx">AddUint64</span><span class="p">(</span><span class="o">&amp;</span><span class="nx">ops</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<div class="highlight"><pre> <span class="k">go</span> <span class="kd">func</span><span class="p">()</span> <span class="p">{</span>
<span class="k">for</span> <span class="nx">c</span> <span class="o">:=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">c</span> <span class="p">&lt;</span> <span class="mi">1000</span><span class="p">;</span> <span class="nx">c</span><span class="o">++</span> <span class="p">{</span>
</pre></div>
</td>
@ -116,13 +143,13 @@ address of our <code>ops</code> counter with the
<tr>
<td class="docs">
<p>Wait a bit between increments.</p>
</td>
<td class="code leading">
<div class="highlight"><pre> <span class="nx">time</span><span class="p">.</span><span class="nx">Sleep</span><span class="p">(</span><span class="nx">time</span><span class="p">.</span><span class="nx">Millisecond</span><span class="p">)</span>
<div class="highlight"><pre> <span class="nx">atomic</span><span class="p">.</span><span class="nx">AddUint64</span><span class="p">(</span><span class="o">&amp;</span><span class="nx">ops</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="p">}</span>
<span class="nx">wg</span><span class="p">.</span><span class="nx">Done</span><span class="p">()</span>
<span class="p">}()</span>
<span class="p">}</span>
</pre></div>
@ -132,12 +159,12 @@ address of our <code>ops</code> counter with the
<tr>
<td class="docs">
<p>Wait a second to allow some ops to accumulate.</p>
<p>Wait until all the goroutines are done.</p>
</td>
<td class="code leading">
<div class="highlight"><pre> <span class="nx">time</span><span class="p">.</span><span class="nx">Sleep</span><span class="p">(</span><span class="nx">time</span><span class="p">.</span><span class="nx">Second</span><span class="p">)</span>
<div class="highlight"><pre> <span class="nx">wg</span><span class="p">.</span><span class="nx">Wait</span><span class="p">()</span>
</pre></div>
</td>
@ -145,18 +172,16 @@ address of our <code>ops</code> counter with the
<tr>
<td class="docs">
<p>In order to safely use the counter while it&rsquo;s still
being updated by other goroutines, we extract a
copy of the current value into <code>opsFinal</code> via
<code>LoadUint64</code>. As above we need to give this
function the memory address <code>&amp;ops</code> from which to
fetch the value.</p>
<p>It&rsquo;s safe to access <code>ops</code> now because we know
no other goroutine is writing to it. Reading
atomics safely while they are being updated is
also possible, using functions like
<code>atomic.LoadUint64</code>.</p>
</td>
<td class="code">
<div class="highlight"><pre> <span class="nx">opsFinal</span> <span class="o">:=</span> <span class="nx">atomic</span><span class="p">.</span><span class="nx">LoadUint64</span><span class="p">(</span><span class="o">&amp;</span><span class="nx">ops</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="s">&quot;ops:&quot;</span><span class="p">,</span> <span class="nx">opsFinal</span><span class="p">)</span>
<div class="highlight"><pre> <span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="s">&quot;ops:&quot;</span><span class="p">,</span> <span class="nx">ops</span><span class="p">)</span>
<span class="p">}</span>
</pre></div>
@ -169,14 +194,18 @@ fetch the value.</p>
<tr>
<td class="docs">
<p>Running the program shows that we executed about
40,000 operations.</p>
<p>We expect to get exactly 50,000 operations. Had we
used the non-atomic <code>ops++</code> to increment the counter,
we&rsquo;d likely get a different number, changing between
runs, because the goroutines would interfere with
each other. Moreover, we&rsquo;d get data race failures
when running with the <code>-race</code> flag.</p>
</td>
<td class="code leading">
<div class="highlight"><pre><span class="gp">$</span> go run atomic-counters.go
<span class="go">ops: 41419</span>
<span class="go">ops: 50000</span>
</pre></div>
</td>
@ -205,5 +234,10 @@ state.</p>
by <a href="https://markmcgranaghan.com">Mark McGranaghan</a> | <a href="https://github.com/mmcgrana/gobyexample/blob/master/examples/atomic-counters">source</a> | <a href="https://github.com/mmcgrana/gobyexample#license">license</a>
</p>
</div>
<script>
var codeLines = [];
codeLines.push('');codeLines.push('package main\u000A');codeLines.push('import (\u000A \"fmt\"\u000A \"sync\"\u000A \"sync/atomic\"\u000A)\u000A');codeLines.push('func main() {\u000A');codeLines.push(' var ops uint64\u000A');codeLines.push(' var wg sync.WaitGroup\u000A');codeLines.push(' for i := 0; i \x3C 50; i++ {\u000A wg.Add(1)\u000A');codeLines.push(' go func() {\u000A for c := 0; c \x3C 1000; c++ {\u000A');codeLines.push(' atomic.AddUint64(&ops, 1)\u000A }\u000A wg.Done()\u000A }()\u000A }\u000A');codeLines.push(' wg.Wait()\u000A');codeLines.push(' fmt.Println(\"ops:\", ops)\u000A}\u000A');codeLines.push('');codeLines.push('');
</script>
<script src="site.js" async></script>
</body>
</html>

29
public/base64-encoding generated
View File

@ -5,6 +5,20 @@
<title>Go by Example: Base64 Encoding</title>
<link rel=stylesheet href="site.css">
</head>
<script>
onkeydown = (e) => {
if (e.key == "ArrowLeft") {
window.location.href = 'sha1-hashes';
}
if (e.key == "ArrowRight") {
window.location.href = 'reading-files';
}
}
</script>
<body>
<div class="example" id="base64-encoding">
<h2><a href="./">Go by Example</a>: Base64 Encoding</h2>
@ -28,9 +42,7 @@ encoding/decoding</a>.</p>
</td>
<td class="code leading">
<a href="http://play.golang.org/p/y_QTcqdkvZh">
<img title="Run code" class="run" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAPCAYAAADtc08vAAAABGdBTUEAANbY1E9YMgAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJ1SURBVCjPY/j//z8DMu7o6GAAgpQgD9tLqcmJH4KDg14aaik/MtdXe2ZjY6OCrh6Fs2jRYmZ9Pd05M9uL/u9dPfU/CLS0dfxvKIz/X5Dg/z8pKdkGqwGpqakMUdExDHJSYqt37tjxf+qUSf9rc2P+79298/+RA3v+H1zV///o6r7/DrbWFQkJiQwxMTGoBjAxMTpKiQmuqMuP/f/xw/v/J0+f/W9tbvTfxVLn/8rJVf+v757z/96hRf8TQtxuCQmLMjk4OKAawMfDVWVvrvd85eTq/7tXTP6/e/XM/22lif9LCnL+b13Q/v/Kzln/L++c/X/7/Jb/VpYWuZFRUagGAAErEBtlxvi+vn944f9L26cDNcz6v21R9/8zm6aC2SBDbu+f/78kK+4/L79AO7oBYCAqxD/57JZp/y/tmPX/wrYZ/6+CbAayD6zs/78daBjIgPayFJAGG6wGAIFAcpjH/dv7F4ANABuya/b/Od3l/ye2V/+/tnv2/7ldxSANmrgMYGBhZg7fuagD7GyYIeeBrrqwdRrQgLn/l02sBGkwwWkAEAjV5EZ/vQV0LswAGAYZsLC3DKTBAJ8BzCkRni/uHFyIYcAtoNc6ypL/ANVIohigrKwMxqqqqgxMzKzM6VHeL+6iGQAKzDtAV5XlJv3n5uFLRTHgzZs3YPzz50+GwqJiPitD9Y8Pjy4BB+CNvfP+3wUmIpAhhckhr3X19LodHZ28UQxQU1MDYw0NDQYBAQEeoBOTK7JjP2xf3Pt/bkfB/4KkoDcKMmIL5OXlFerq6hhu3rzJgC8MwMDYxGSfm5vbVn9/f0cgVxAkpqioyFBfX49iAACbTAK+xT3CzgAAAABJRU5ErkJggg==" />
</a>
<a href="http://play.golang.org/p/V3oV1bvh94k"><img title="Run code" src="play.png" class="run" /></a><img title="Copy code" src="clipboard.png" class="copy" />
<div class="highlight"><pre><span class="kn">package</span> <span class="nx">main</span>
</pre></div>
@ -46,8 +58,10 @@ save us some space below.</p>
</td>
<td class="code leading">
<div class="highlight"><pre><span class="kn">import</span> <span class="nx">b64</span> <span class="s">&quot;encoding/base64&quot;</span>
<span class="kn">import</span> <span class="s">&quot;fmt&quot;</span>
<div class="highlight"><pre><span class="kn">import</span> <span class="p">(</span>
<span class="nx">b64</span> <span class="s">&quot;encoding/base64&quot;</span>
<span class="s">&quot;fmt&quot;</span>
<span class="p">)</span>
</pre></div>
</td>
@ -175,5 +189,10 @@ but they both decode to the original string as desired.</p>
by <a href="https://markmcgranaghan.com">Mark McGranaghan</a> | <a href="https://github.com/mmcgrana/gobyexample/blob/master/examples/base64-encoding">source</a> | <a href="https://github.com/mmcgrana/gobyexample#license">license</a>
</p>
</div>
<script>
var codeLines = [];
codeLines.push('');codeLines.push('package main\u000A');codeLines.push('import (\u000A b64 \"encoding/base64\"\u000A \"fmt\"\u000A)\u000A');codeLines.push('func main() {\u000A');codeLines.push(' data := \"abc123!?$*&()\'-=@~\"\u000A');codeLines.push(' sEnc := b64.StdEncoding.EncodeToString([]byte(data))\u000A fmt.Println(sEnc)\u000A');codeLines.push(' sDec, _ := b64.StdEncoding.DecodeString(sEnc)\u000A fmt.Println(string(sDec))\u000A fmt.Println()\u000A');codeLines.push(' uEnc := b64.URLEncoding.EncodeToString([]byte(data))\u000A fmt.Println(uEnc)\u000A uDec, _ := b64.URLEncoding.DecodeString(uEnc)\u000A fmt.Println(string(uDec))\u000A}\u000A');codeLines.push('');codeLines.push('');
</script>
<script src="site.js" async></script>
</body>
</html>

View File

@ -5,6 +5,20 @@
<title>Go by Example: Channel Buffering</title>
<link rel=stylesheet href="site.css">
</head>
<script>
onkeydown = (e) => {
if (e.key == "ArrowLeft") {
window.location.href = 'channels';
}
if (e.key == "ArrowRight") {
window.location.href = 'channel-synchronization';
}
}
</script>
<body>
<div class="example" id="channel-buffering">
<h2><a href="./">Go by Example</a>: Channel Buffering</h2>
@ -32,9 +46,7 @@ those values.</p>
</td>
<td class="code leading">
<a href="http://play.golang.org/p/mPoF-Xi-rip">
<img title="Run code" class="run" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAPCAYAAADtc08vAAAABGdBTUEAANbY1E9YMgAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJ1SURBVCjPY/j//z8DMu7o6GAAgpQgD9tLqcmJH4KDg14aaik/MtdXe2ZjY6OCrh6Fs2jRYmZ9Pd05M9uL/u9dPfU/CLS0dfxvKIz/X5Dg/z8pKdkGqwGpqakMUdExDHJSYqt37tjxf+qUSf9rc2P+79298/+RA3v+H1zV///o6r7/DrbWFQkJiQwxMTGoBjAxMTpKiQmuqMuP/f/xw/v/J0+f/W9tbvTfxVLn/8rJVf+v757z/96hRf8TQtxuCQmLMjk4OKAawMfDVWVvrvd85eTq/7tXTP6/e/XM/22lif9LCnL+b13Q/v/Kzln/L++c/X/7/Jb/VpYWuZFRUagGAAErEBtlxvi+vn944f9L26cDNcz6v21R9/8zm6aC2SBDbu+f/78kK+4/L79AO7oBYCAqxD/57JZp/y/tmPX/wrYZ/6+CbAayD6zs/78daBjIgPayFJAGG6wGAIFAcpjH/dv7F4ANABuya/b/Od3l/ye2V/+/tnv2/7ldxSANmrgMYGBhZg7fuagD7GyYIeeBrrqwdRrQgLn/l02sBGkwwWkAEAjV5EZ/vQV0LswAGAYZsLC3DKTBAJ8BzCkRni/uHFyIYcAtoNc6ypL/ANVIohigrKwMxqqqqgxMzKzM6VHeL+6iGQAKzDtAV5XlJv3n5uFLRTHgzZs3YPzz50+GwqJiPitD9Y8Pjy4BB+CNvfP+3wUmIpAhhckhr3X19LodHZ28UQxQU1MDYw0NDQYBAQEeoBOTK7JjP2xf3Pt/bkfB/4KkoDcKMmIL5OXlFerq6hhu3rzJgC8MwMDYxGSfm5vbVn9/f0cgVxAkpqioyFBfX49iAACbTAK+xT3CzgAAAABJRU5ErkJggg==" />
</a>
<a href="http://play.golang.org/p/mPoF-Xi-rip"><img title="Run code" src="play.png" class="run" /></a><img title="Copy code" src="clipboard.png" class="copy" />
<div class="highlight"><pre><span class="kn">package</span> <span class="nx">main</span>
</pre></div>
@ -139,5 +151,10 @@ concurrent receive.</p>
by <a href="https://markmcgranaghan.com">Mark McGranaghan</a> | <a href="https://github.com/mmcgrana/gobyexample/blob/master/examples/channel-buffering">source</a> | <a href="https://github.com/mmcgrana/gobyexample#license">license</a>
</p>
</div>
<script>
var codeLines = [];
codeLines.push('');codeLines.push('package main\u000A');codeLines.push('import \"fmt\"\u000A');codeLines.push('func main() {\u000A');codeLines.push(' messages := make(chan string, 2)\u000A');codeLines.push(' messages \x3C- \"buffered\"\u000A messages \x3C- \"channel\"\u000A');codeLines.push(' fmt.Println(\x3C-messages)\u000A fmt.Println(\x3C-messages)\u000A}\u000A');codeLines.push('');
</script>
<script src="site.js" async></script>
</body>
</html>

View File

@ -5,6 +5,20 @@
<title>Go by Example: Channel Directions</title>
<link rel=stylesheet href="site.css">
</head>
<script>
onkeydown = (e) => {
if (e.key == "ArrowLeft") {
window.location.href = 'channel-synchronization';
}
if (e.key == "ArrowRight") {
window.location.href = 'select';
}
}
</script>
<body>
<div class="example" id="channel-directions">
<h2><a href="./">Go by Example</a>: Channel Directions</h2>
@ -30,9 +44,7 @@ the program.</p>
</td>
<td class="code leading">
<a href="http://play.golang.org/p/Jnn9_9hC48c">
<img title="Run code" class="run" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAPCAYAAADtc08vAAAABGdBTUEAANbY1E9YMgAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJ1SURBVCjPY/j//z8DMu7o6GAAgpQgD9tLqcmJH4KDg14aaik/MtdXe2ZjY6OCrh6Fs2jRYmZ9Pd05M9uL/u9dPfU/CLS0dfxvKIz/X5Dg/z8pKdkGqwGpqakMUdExDHJSYqt37tjxf+qUSf9rc2P+79298/+RA3v+H1zV///o6r7/DrbWFQkJiQwxMTGoBjAxMTpKiQmuqMuP/f/xw/v/J0+f/W9tbvTfxVLn/8rJVf+v757z/96hRf8TQtxuCQmLMjk4OKAawMfDVWVvrvd85eTq/7tXTP6/e/XM/22lif9LCnL+b13Q/v/Kzln/L++c/X/7/Jb/VpYWuZFRUagGAAErEBtlxvi+vn944f9L26cDNcz6v21R9/8zm6aC2SBDbu+f/78kK+4/L79AO7oBYCAqxD/57JZp/y/tmPX/wrYZ/6+CbAayD6zs/78daBjIgPayFJAGG6wGAIFAcpjH/dv7F4ANABuya/b/Od3l/ye2V/+/tnv2/7ldxSANmrgMYGBhZg7fuagD7GyYIeeBrrqwdRrQgLn/l02sBGkwwWkAEAjV5EZ/vQV0LswAGAYZsLC3DKTBAJ8BzCkRni/uHFyIYcAtoNc6ypL/ANVIohigrKwMxqqqqgxMzKzM6VHeL+6iGQAKzDtAV5XlJv3n5uFLRTHgzZs3YPzz50+GwqJiPitD9Y8Pjy4BB+CNvfP+3wUmIpAhhckhr3X19LodHZ28UQxQU1MDYw0NDQYBAQEeoBOTK7JjP2xf3Pt/bkfB/4KkoDcKMmIL5OXlFerq6hhu3rzJgC8MwMDYxGSfm5vbVn9/f0cgVxAkpqioyFBfX49iAACbTAK+xT3CzgAAAABJRU5ErkJggg==" />
</a>
<a href="http://play.golang.org/p/Jnn9_9hC48c"><img title="Run code" src="play.png" class="run" /></a><img title="Copy code" src="clipboard.png" class="copy" />
<div class="highlight"><pre><span class="kn">package</span> <span class="nx">main</span>
</pre></div>
@ -131,5 +143,10 @@ receive on this channel.</p>
by <a href="https://markmcgranaghan.com">Mark McGranaghan</a> | <a href="https://github.com/mmcgrana/gobyexample/blob/master/examples/channel-directions">source</a> | <a href="https://github.com/mmcgrana/gobyexample#license">license</a>
</p>
</div>
<script>
var codeLines = [];
codeLines.push('');codeLines.push('package main\u000A');codeLines.push('import \"fmt\"\u000A');codeLines.push('func ping(pings chan\x3C- string, msg string) {\u000A pings \x3C- msg\u000A}\u000A');codeLines.push('func pong(pings \x3C-chan string, pongs chan\x3C- string) {\u000A msg := \x3C-pings\u000A pongs \x3C- msg\u000A}\u000A');codeLines.push('func main() {\u000A pings := make(chan string, 1)\u000A pongs := make(chan string, 1)\u000A ping(pings, \"passed message\")\u000A pong(pings, pongs)\u000A fmt.Println(\x3C-pongs)\u000A}\u000A');codeLines.push('');
</script>
<script src="site.js" async></script>
</body>
</html>

View File

@ -5,6 +5,20 @@
<title>Go by Example: Channel Synchronization</title>
<link rel=stylesheet href="site.css">
</head>
<script>
onkeydown = (e) => {
if (e.key == "ArrowLeft") {
window.location.href = 'channel-buffering';
}
if (e.key == "ArrowRight") {
window.location.href = 'channel-directions';
}
}
</script>
<body>
<div class="example" id="channel-synchronization">
<h2><a href="./">Go by Example</a>: Channel Synchronization</h2>
@ -31,9 +45,7 @@ you may prefer to use a <a href="waitgroups">WaitGroup</a>.</p>
</td>
<td class="code leading">
<a href="http://play.golang.org/p/8lmP8beav0p">
<img title="Run code" class="run" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAPCAYAAADtc08vAAAABGdBTUEAANbY1E9YMgAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJ1SURBVCjPY/j//z8DMu7o6GAAgpQgD9tLqcmJH4KDg14aaik/MtdXe2ZjY6OCrh6Fs2jRYmZ9Pd05M9uL/u9dPfU/CLS0dfxvKIz/X5Dg/z8pKdkGqwGpqakMUdExDHJSYqt37tjxf+qUSf9rc2P+79298/+RA3v+H1zV///o6r7/DrbWFQkJiQwxMTGoBjAxMTpKiQmuqMuP/f/xw/v/J0+f/W9tbvTfxVLn/8rJVf+v757z/96hRf8TQtxuCQmLMjk4OKAawMfDVWVvrvd85eTq/7tXTP6/e/XM/22lif9LCnL+b13Q/v/Kzln/L++c/X/7/Jb/VpYWuZFRUagGAAErEBtlxvi+vn944f9L26cDNcz6v21R9/8zm6aC2SBDbu+f/78kK+4/L79AO7oBYCAqxD/57JZp/y/tmPX/wrYZ/6+CbAayD6zs/78daBjIgPayFJAGG6wGAIFAcpjH/dv7F4ANABuya/b/Od3l/ye2V/+/tnv2/7ldxSANmrgMYGBhZg7fuagD7GyYIeeBrrqwdRrQgLn/l02sBGkwwWkAEAjV5EZ/vQV0LswAGAYZsLC3DKTBAJ8BzCkRni/uHFyIYcAtoNc6ypL/ANVIohigrKwMxqqqqgxMzKzM6VHeL+6iGQAKzDtAV5XlJv3n5uFLRTHgzZs3YPzz50+GwqJiPitD9Y8Pjy4BB+CNvfP+3wUmIpAhhckhr3X19LodHZ28UQxQU1MDYw0NDQYBAQEeoBOTK7JjP2xf3Pt/bkfB/4KkoDcKMmIL5OXlFerq6hhu3rzJgC8MwMDYxGSfm5vbVn9/f0cgVxAkpqioyFBfX49iAACbTAK+xT3CzgAAAABJRU5ErkJggg==" />
</a>
<a href="http://play.golang.org/p/fe9If6OhYMk"><img title="Run code" src="play.png" class="run" /></a><img title="Copy code" src="clipboard.png" class="copy" />
<div class="highlight"><pre><span class="kn">package</span> <span class="nx">main</span>
</pre></div>
@ -46,8 +58,10 @@ you may prefer to use a <a href="waitgroups">WaitGroup</a>.</p>
</td>
<td class="code leading">
<div class="highlight"><pre><span class="kn">import</span> <span class="s">&quot;fmt&quot;</span>
<span class="kn">import</span> <span class="s">&quot;time&quot;</span>
<div class="highlight"><pre><span class="kn">import</span> <span class="p">(</span>
<span class="s">&quot;fmt&quot;</span>
<span class="s">&quot;time&quot;</span>
<span class="p">)</span>
</pre></div>
</td>
@ -168,5 +182,10 @@ started.</p>
by <a href="https://markmcgranaghan.com">Mark McGranaghan</a> | <a href="https://github.com/mmcgrana/gobyexample/blob/master/examples/channel-synchronization">source</a> | <a href="https://github.com/mmcgrana/gobyexample#license">license</a>
</p>
</div>
<script>
var codeLines = [];
codeLines.push('');codeLines.push('package main\u000A');codeLines.push('import (\u000A \"fmt\"\u000A \"time\"\u000A)\u000A');codeLines.push('func worker(done chan bool) {\u000A fmt.Print(\"working...\")\u000A time.Sleep(time.Second)\u000A fmt.Println(\"done\")\u000A');codeLines.push(' done \x3C- true\u000A}\u000A');codeLines.push('func main() {\u000A');codeLines.push(' done := make(chan bool, 1)\u000A go worker(done)\u000A');codeLines.push(' \x3C-done\u000A}\u000A');codeLines.push('');codeLines.push('');
</script>
<script src="site.js" async></script>
</body>
</html>

23
public/channels generated
View File

@ -5,6 +5,20 @@
<title>Go by Example: Channels</title>
<link rel=stylesheet href="site.css">
</head>
<script>
onkeydown = (e) => {
if (e.key == "ArrowLeft") {
window.location.href = 'goroutines';
}
if (e.key == "ArrowRight") {
window.location.href = 'channel-buffering';
}
}
</script>
<body>
<div class="example" id="channels">
<h2><a href="./">Go by Example</a>: Channels</h2>
@ -30,9 +44,7 @@ goroutine.</p>
</td>
<td class="code leading">
<a href="http://play.golang.org/p/bRGMAqinovA">
<img title="Run code" class="run" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAPCAYAAADtc08vAAAABGdBTUEAANbY1E9YMgAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJ1SURBVCjPY/j//z8DMu7o6GAAgpQgD9tLqcmJH4KDg14aaik/MtdXe2ZjY6OCrh6Fs2jRYmZ9Pd05M9uL/u9dPfU/CLS0dfxvKIz/X5Dg/z8pKdkGqwGpqakMUdExDHJSYqt37tjxf+qUSf9rc2P+79298/+RA3v+H1zV///o6r7/DrbWFQkJiQwxMTGoBjAxMTpKiQmuqMuP/f/xw/v/J0+f/W9tbvTfxVLn/8rJVf+v757z/96hRf8TQtxuCQmLMjk4OKAawMfDVWVvrvd85eTq/7tXTP6/e/XM/22lif9LCnL+b13Q/v/Kzln/L++c/X/7/Jb/VpYWuZFRUagGAAErEBtlxvi+vn944f9L26cDNcz6v21R9/8zm6aC2SBDbu+f/78kK+4/L79AO7oBYCAqxD/57JZp/y/tmPX/wrYZ/6+CbAayD6zs/78daBjIgPayFJAGG6wGAIFAcpjH/dv7F4ANABuya/b/Od3l/ye2V/+/tnv2/7ldxSANmrgMYGBhZg7fuagD7GyYIeeBrrqwdRrQgLn/l02sBGkwwWkAEAjV5EZ/vQV0LswAGAYZsLC3DKTBAJ8BzCkRni/uHFyIYcAtoNc6ypL/ANVIohigrKwMxqqqqgxMzKzM6VHeL+6iGQAKzDtAV5XlJv3n5uFLRTHgzZs3YPzz50+GwqJiPitD9Y8Pjy4BB+CNvfP+3wUmIpAhhckhr3X19LodHZ28UQxQU1MDYw0NDQYBAQEeoBOTK7JjP2xf3Pt/bkfB/4KkoDcKMmIL5OXlFerq6hhu3rzJgC8MwMDYxGSfm5vbVn9/f0cgVxAkpqioyFBfX49iAACbTAK+xT3CzgAAAABJRU5ErkJggg==" />
</a>
<a href="http://play.golang.org/p/bRGMAqinovA"><img title="Run code" src="play.png" class="run" /></a><img title="Copy code" src="clipboard.png" class="copy" />
<div class="highlight"><pre><span class="kn">package</span> <span class="nx">main</span>
</pre></div>
@ -154,5 +166,10 @@ message without having to use any other synchronization.</p>
by <a href="https://markmcgranaghan.com">Mark McGranaghan</a> | <a href="https://github.com/mmcgrana/gobyexample/blob/master/examples/channels">source</a> | <a href="https://github.com/mmcgrana/gobyexample#license">license</a>
</p>
</div>
<script>
var codeLines = [];
codeLines.push('');codeLines.push('package main\u000A');codeLines.push('import \"fmt\"\u000A');codeLines.push('func main() {\u000A');codeLines.push(' messages := make(chan string)\u000A');codeLines.push(' go func() { messages \x3C- \"ping\" }()\u000A');codeLines.push(' msg := \x3C-messages\u000A fmt.Println(msg)\u000A}\u000A');codeLines.push('');codeLines.push('');
</script>
<script src="site.js" async></script>
</body>
</html>

BIN
public/clipboard.png generated Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 488 B

View File

@ -5,6 +5,20 @@
<title>Go by Example: Closing Channels</title>
<link rel=stylesheet href="site.css">
</head>
<script>
onkeydown = (e) => {
if (e.key == "ArrowLeft") {
window.location.href = 'non-blocking-channel-operations';
}
if (e.key == "ArrowRight") {
window.location.href = 'range-over-channels';
}
}
</script>
<body>
<div class="example" id="closing-channels">
<h2><a href="./">Go by Example</a>: Closing Channels</h2>
@ -29,9 +43,7 @@ completion to the channel&rsquo;s receivers.</p>
</td>
<td class="code leading">
<a href="http://play.golang.org/p/mkz69rVMHs6">
<img title="Run code" class="run" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAPCAYAAADtc08vAAAABGdBTUEAANbY1E9YMgAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJ1SURBVCjPY/j//z8DMu7o6GAAgpQgD9tLqcmJH4KDg14aaik/MtdXe2ZjY6OCrh6Fs2jRYmZ9Pd05M9uL/u9dPfU/CLS0dfxvKIz/X5Dg/z8pKdkGqwGpqakMUdExDHJSYqt37tjxf+qUSf9rc2P+79298/+RA3v+H1zV///o6r7/DrbWFQkJiQwxMTGoBjAxMTpKiQmuqMuP/f/xw/v/J0+f/W9tbvTfxVLn/8rJVf+v757z/96hRf8TQtxuCQmLMjk4OKAawMfDVWVvrvd85eTq/7tXTP6/e/XM/22lif9LCnL+b13Q/v/Kzln/L++c/X/7/Jb/VpYWuZFRUagGAAErEBtlxvi+vn944f9L26cDNcz6v21R9/8zm6aC2SBDbu+f/78kK+4/L79AO7oBYCAqxD/57JZp/y/tmPX/wrYZ/6+CbAayD6zs/78daBjIgPayFJAGG6wGAIFAcpjH/dv7F4ANABuya/b/Od3l/ye2V/+/tnv2/7ldxSANmrgMYGBhZg7fuagD7GyYIeeBrrqwdRrQgLn/l02sBGkwwWkAEAjV5EZ/vQV0LswAGAYZsLC3DKTBAJ8BzCkRni/uHFyIYcAtoNc6ypL/ANVIohigrKwMxqqqqgxMzKzM6VHeL+6iGQAKzDtAV5XlJv3n5uFLRTHgzZs3YPzz50+GwqJiPitD9Y8Pjy4BB+CNvfP+3wUmIpAhhckhr3X19LodHZ28UQxQU1MDYw0NDQYBAQEeoBOTK7JjP2xf3Pt/bkfB/4KkoDcKMmIL5OXlFerq6hhu3rzJgC8MwMDYxGSfm5vbVn9/f0cgVxAkpqioyFBfX49iAACbTAK+xT3CzgAAAABJRU5ErkJggg==" />
</a>
<a href="http://play.golang.org/p/mkz69rVMHs6"><img title="Run code" src="play.png" class="run" /></a><img title="Copy code" src="clipboard.png" class="copy" />
<div class="highlight"><pre><span class="kn">package</span> <span class="nx">main</span>
</pre></div>
@ -180,5 +192,10 @@ example: <code>range</code> over channels.</p>
by <a href="https://markmcgranaghan.com">Mark McGranaghan</a> | <a href="https://github.com/mmcgrana/gobyexample/blob/master/examples/closing-channels">source</a> | <a href="https://github.com/mmcgrana/gobyexample#license">license</a>
</p>
</div>
<script>
var codeLines = [];
codeLines.push('');codeLines.push('package main\u000A');codeLines.push('import \"fmt\"\u000A');codeLines.push('func main() {\u000A jobs := make(chan int, 5)\u000A done := make(chan bool)\u000A');codeLines.push(' go func() {\u000A for {\u000A j, more := \x3C-jobs\u000A if more {\u000A fmt.Println(\"received job\", j)\u000A } else {\u000A fmt.Println(\"received all jobs\")\u000A done \x3C- true\u000A return\u000A }\u000A }\u000A }()\u000A');codeLines.push(' for j := 1; j \x3C= 3; j++ {\u000A jobs \x3C- j\u000A fmt.Println(\"sent job\", j)\u000A }\u000A close(jobs)\u000A fmt.Println(\"sent all jobs\")\u000A');codeLines.push(' \x3C-done\u000A}\u000A');codeLines.push('');codeLines.push('');
</script>
<script src="site.js" async></script>
</body>
</html>

Some files were not shown because too many files have changed in this diff Show More