├── .gitignore ├── Makefile ├── README.mdown ├── arrays ├── .gitignore └── arrays.go ├── chaint1 ├── .gitignore └── chaint1.go ├── chanasyn ├── .gitignore └── chanasyn.go ├── chanfan01 ├── .gitignore └── chanfan01.go ├── chanfan02 ├── .gitignore └── chanfan02.go ├── chanfan03 ├── .gitignore └── chanfan03.go ├── chanfan04 ├── .gitignore └── chanfan04.go ├── chanfan05 ├── .gitignore └── chanfan05.go ├── chanfan06 ├── .gitignore └── chanfan06.go ├── chanfan07 ├── .gitignore └── chanfan07.go ├── chanfan08 ├── .gitignore └── chanfan08.go ├── chanfanout ├── .gitignore └── chanfanout.go ├── chanfanout2 ├── .gitignore └── chanfanout2.go ├── chanloop ├── .gitignore └── chanloop.go ├── channelLock ├── .gitignore ├── channelLock.go └── fastQuit │ ├── .gitignore │ └── fastQuit.go ├── chanokt ├── .gitignore └── chanokt.go ├── chanrange ├── .gitignore └── chanrange.go ├── chanshunt ├── .gitignore └── chanshunt.go ├── chanshunt_2 ├── .gitignore └── chanshunt_2.go ├── chansvr1 ├── .gitignore └── chansvr1.go ├── chansvr2 ├── .gitignore └── chansvr2.go ├── chansyn ├── .gitignore └── chansyn.go ├── chantest ├── .gitignore └── chantest.go ├── charshow ├── .gitignore └── charshow.go ├── dateshow ├── .gitignore └── dateshow.go ├── defer ├── .gitignore └── defer.go ├── demo_templates ├── call │ ├── .gitignore │ └── call.go ├── conditions │ ├── .gitignore │ └── conditions.go ├── functions │ ├── .gitignore │ └── functions.go ├── golangtutorials │ ├── fieldname │ │ ├── .gitignore │ │ └── fieldname.go │ ├── printf │ │ ├── .gitignore │ │ └── printf.go │ ├── revquotes │ │ ├── .gitignore │ │ └── revquotes.go │ ├── tvars │ │ ├── .gitignore │ │ └── tvars.go │ └── twithend │ │ ├── .gitignore │ │ └── twithend.go ├── insdata │ ├── .gitignore │ └── insdata.go ├── jst │ ├── .gitignore │ └── jst.go ├── must │ ├── .gitignore │ └── must.go ├── nestedfields │ ├── .gitignore │ └── nestedfields.go ├── nestedtemplates │ ├── .gitignore │ ├── nestedtemplages.go │ └── tmplfiles │ │ ├── content.tmpl │ │ ├── footer.tmpl │ │ └── header.tmpl ├── pipelines │ ├── .gitignore │ └── pipelines.go └── readme.txt ├── dtemplex1 ├── .gitignore └── dtemplex1.go ├── dtemplex2 ├── .gitignore └── dtemplex2.go ├── envshow ├── .gitignore └── envshow.go ├── errtest ├── .gitignore └── errtest.go ├── fib ├── .gitignore └── fib.go ├── fib_embellished ├── .gitignore └── fib_embellished.go ├── fib_userop ├── .gitignore └── fib_userop.go ├── fileread ├── .gitignore ├── data.txt ├── datacrlf.txt └── fileread.go ├── filescan ├── .gitignore ├── filescan.go └── t.txt ├── flagdemo ├── .gitignore └── flagdemo.go ├── force_type ├── .gitignore └── force_type.go ├── func_lit ├── .gitignore └── func_lit.go ├── func_ret ├── .gitignore └── func_ret.go ├── fwalker ├── .gitignore └── fwalker.go ├── gio12gs01 ├── .gitignore └── gio12gs01.go ├── gio12gs02 ├── .gitignore └── gio12gs02.go ├── gio12gs03 ├── .gitignore └── gio12gs03.go ├── gio12gs04 ├── .gitignore └── gio12gs04.go ├── gio12gs05 ├── .gitignore └── gio12gs05.go ├── gobdemo ├── .gitignore └── gobdemo.go ├── gorsynchs ├── .gitignore ├── chanex │ ├── .gitignore │ └── chanex.go ├── mutexex │ ├── .gitignore │ └── mutexex.go └── wgroupex │ ├── .gitignore │ └── wgroupex.go ├── gortns01 ├── .gitignore └── gortns01.go ├── greddit ├── .gitignore └── greddit.go ├── gt044 ├── .gitignore └── gt044.go ├── gt045 ├── .gitignore └── gt045.go ├── hello ├── .gitignore └── hello.go ├── hello_small ├── .gitignore └── hello_small.go ├── httpserv ├── .gitignore └── httpserv.go ├── interface_01 ├── .gitignore └── interface_01.go ├── interface_02 ├── .gitignore └── interface_02.go ├── interface_03 ├── .gitignore └── interface_03.go ├── interface_04 ├── .gitignore └── interface_04.go ├── interface_04a ├── .gitignore └── interface_04a.go ├── interface_04b ├── .gitignore └── interface_04b.go ├── interface_05 ├── .gitignore └── interface_05.go ├── list ├── .gitignore └── list.go ├── list_struct ├── .gitignore └── list_struct.go ├── loghello ├── .gitignore └── loghello.go ├── mapcaph ├── .gitignore └── mapcaph.go ├── mapmapstr ├── .gitignore └── mapmapstr.go ├── mapptrs ├── .gitignore └── mapptrs.go ├── maps ├── .gitignore └── maps.go ├── maps_merge ├── .gitignore └── maps_merge.go ├── maps_ss ├── .gitignore └── maps_ss.go ├── methods ├── .gitignore └── methods.go ├── netcon ├── .gitignore └── netcon.go ├── numbers ├── .gitignore ├── README.txt ├── numbers.go └── numbers_test.go ├── numconv ├── .gitignore └── numconv.go ├── oltesta ├── .gitignore └── oltesta.go ├── panrecov ├── .gitignore └── panrecov.go ├── pgmdir ├── .gitignore └── pgmdir.go ├── rand_between ├── .gitignore ├── rand_between.go └── rb_test.go ├── rangecopy ├── .gitignore └── rangecopy.go ├── ranges ├── .gitignore └── ranges.go ├── recover ├── .gitignore └── recover.go ├── reflmem ├── .gitignore └── reflmem.go ├── runpprof ├── .gitignore └── runpprof.go ├── shax ├── .gitignore └── shax.go ├── shifter ├── .gitignore └── shifter.go ├── show64 ├── .gitignore └── show64.go ├── showallocs ├── .gitignore └── showallocs.go ├── showgo ├── .gitignore └── showgo.go ├── showmac ├── .gitignore └── showmac.go ├── showpprof ├── .gitignore └── showpprof.go ├── showrtc ├── .gitignore └── showrtc.go ├── showsetcpus ├── .gitignore └── showsetcpus.go ├── showtime ├── .gitignore └── showtime.go ├── sigshow ├── .gitignore └── sigshow.go ├── sl3index ├── .gitignore └── sl3index.go ├── slappmult ├── .gitignore └── slappmult.go ├── slblog ├── .gitignore └── slblog.go ├── sldemo ├── .gitignore └── sldemo.go ├── sliceappt ├── .gitignore └── sliceappt.go ├── slices ├── .gitignore └── slices.go ├── slofsl ├── .gitignore └── slofsl.go ├── slofsl2 ├── .gitignore └── slofsl2.go ├── sltricks ├── .gitignore └── sltricks.go ├── sortex ├── .gitignore └── sortex.go ├── sqlex ├── .gitignore ├── foo.db └── sqlex.go ├── ssl ├── .gitignore ├── README.mdown ├── certinfo │ ├── .gitignore │ └── certinfo.go ├── certs │ ├── .gitignore │ ├── ca │ │ ├── ca.crt │ │ ├── ca.key │ │ ├── ca.pks │ │ └── ca.store │ ├── client │ │ ├── client.crt │ │ ├── client.csr │ │ ├── client.key │ │ ├── client.pks │ │ └── client.store │ └── server │ │ ├── server.crt │ │ ├── server.csr │ │ ├── server.key │ │ ├── server.pks │ │ └── server.store ├── client1 │ ├── .gitignore │ └── client1.go ├── client2 │ ├── .gitignore │ └── client2.go ├── client3 │ ├── .gitignore │ └── client3.go ├── client4 │ ├── .gitignore │ └── client4.go └── pemload │ ├── .gitignore │ └── pemload.go ├── stacktrace ├── .gitignore └── stacktrace.go ├── stomptest ├── .gitignore ├── receiver1 │ ├── .gitignore │ └── receiver1.go ├── receivernid │ ├── .gitignore │ └── receivernid.go ├── sender │ ├── .gitignore │ └── sender.go ├── sendernid │ ├── .gitignore │ └── sendernid.go ├── sendrcv │ ├── .gitignore │ └── sendrcv.go └── subrecv_examp │ ├── .gitignore │ └── subrecv_examp.go ├── stringlens ├── .gitignore └── stringlens.go ├── strings_utils ├── .gitignore └── strings_utils.go ├── struct ├── .gitignore └── struct.go ├── switch_demo ├── .gitignore └── switch_demo.go ├── symlshow ├── .gitignore └── symlshow.go ├── symltest ├── .gitignore └── symltest.go ├── tcp01 ├── .gitignore └── tcp01.go ├── tcp02 ├── .gitignore └── tcp02.go ├── tcp03 ├── .gitignore └── tcp03.go ├── tcp04 ├── .gitignore └── tcp04.go ├── tcp05 ├── .gitignore └── tcp05.go ├── tcp06 ├── .gitignore └── tcp06.go ├── testgreek ├── .gitignore └── testgreek.go ├── testppack ├── .gitignore └── testppack.go ├── type_String ├── .gitignore └── type_String.go ├── unicloup ├── .gitignore └── unicloup.go ├── unicode_what ├── .gitignore └── unicode_what.go ├── uniques ├── .gitignore └── uniques.go ├── urlshow ├── .gitignore └── urlshow.go ├── utfconv ├── .gitignore └── utfconv.go ├── walker ├── .gitignore └── walker.go ├── xmlshow01 ├── .gitignore ├── data.xml ├── data2.xml └── xmlshow01.go ├── xmlshow02 ├── .gitignore └── xmlshow02.go ├── xmlshow03 ├── .gitignore ├── data.xml └── xmlshow03.go ├── xmlshow04 ├── .gitignore └── xmlshow04.go └── zip_test ├── .gitignore ├── testdata ├── testa.jar └── testfile.zip └── ziptest.go /.gitignore: -------------------------------------------------------------------------------- 1 | # 2 | *.out 3 | *.8 4 | *.6 5 | *~ 6 | main 7 | _* 8 | .idea 9 | # Log files 10 | *.log 11 | # temp files 12 | temp* 13 | 14 | -------------------------------------------------------------------------------- /README.mdown: -------------------------------------------------------------------------------- 1 | Project go-samp, Samples of Simple go Language Programs 2 | ======================================================= 3 | This is a collection of extremely simple examples of using the _go_ 4 | programming language. 5 | 6 | These samples were inspired primarily by the _GoCourseDay#.pdf_ files 7 | previously available in the _go_ distrubution. And some additional experiments. 8 | In particular experiments triggered by documentation provided in the go 9 | distribution. 10 | 11 | Prerequisites 12 | ------------- 13 | 14 | In essence, you need a working _go_ environment, and a few small additions. 15 | 16 | At the current HEAD of master, your go build should be at least: weekly.2012-02-07. 17 | 18 | You need certain basic functions available to you in order to build and run 19 | these _go_ programs. 20 | 21 | These include: 22 | 23 | * the _go_ compiler 24 | * the _go_ linker 25 | * make 26 | 27 | If you are not familiar with _go_, and want to install it and learn the 28 | language, see: 29 | 30 | * http://golang.org 31 | 32 | Additional Setup 33 | ---------------- 34 | 35 | In order to use the _make_ system for these samples, you will need to have 36 | the $GOPATH environment variable properly defined. See the go documentation 37 | for details. 38 | 39 | Although this system is still installed using make, the 'go' tool is used under the 40 | covers. If you require previous versions, please examine previous tags. 41 | 42 | Adjust $GOPATH as necessary for your system. 43 | 44 | Install 45 | ------- 46 | 47 | To install all these samples: 48 | 49 | * clone from or fork on github 50 | * _cd_ to your base git repo directory 51 | * make packages 52 | * make 53 | 54 | Other Education Resources 55 | ------------------------- 56 | 57 | * http://www.slideshare.net/alexander.uni.fiis/learning-go-01 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /arrays/.gitignore: -------------------------------------------------------------------------------- 1 | arrays 2 | arrays.exe 3 | -------------------------------------------------------------------------------- /arrays/arrays.go: -------------------------------------------------------------------------------- 1 | /* 2 | A demonstration of using go arrays and slices. 3 | */ 4 | package main 5 | 6 | import "fmt" 7 | 8 | // 9 | // Function parameter: an array of 3 integers. 10 | // 11 | func f(a [3]int) { 12 | fmt.Println(a) 13 | } 14 | 15 | // 16 | // Function parameter: slice of integers, any length 17 | // Note that slices are not arrays. More like a view onto an array. 18 | // 19 | func fa(a []int) { 20 | fmt.Println(a) 21 | } 22 | 23 | // 24 | // Function parameter: a pointer to an array of 3 integers. 25 | // 26 | func fp(a *[3]int) { 27 | fmt.Println(a) 28 | } 29 | 30 | // 31 | // Function parameter: a pointer to an slice of integers. 32 | // As noted above, this is really a pointer to a slice, *not* a pointer 33 | // to an array. 34 | // 35 | func fsp(a *[]int) { 36 | fmt.Println(a) 37 | } 38 | 39 | /* 40 | 41 | */ 42 | func main() { 43 | // 44 | // Declared array 45 | // 46 | var ar [3]int 47 | f(ar) 48 | fp(&ar) 49 | // 50 | // Array Literal 51 | // 52 | var arb = [3]int{1, 2, 3} 53 | f(arb) 54 | fp(&arb) 55 | // 56 | // This is actually/technically a slice literal, not an array literal. 57 | // 58 | var arc = []int{1, 2, 3, 4, 5} 59 | fa(arc) // Note, different function needed (signature) 60 | fsp(&arc) // .... 61 | // 62 | // ------------------------------------------------------------------------ 63 | // 64 | // Array Literal, implied length of 5. 65 | // 66 | var ard = [...]int{1, 3, 5, 7, 9} 67 | // 68 | // This fails to compile: 69 | // 70 | // fa(ard) 71 | // 72 | // with error messages: 73 | // ..... cannot use ard (type [5]int) as type []int in function argument 74 | // 75 | // This fails to compile: 76 | // 77 | // fsp(&ard) 78 | // 79 | // with error messages: 80 | // ..... cannot use &ard (type *[5]int) as type *[]int in function argument 81 | // 82 | // ------------------------------------------------------------------------ 83 | fmt.Printf("%d\n", len(ard)) 84 | // 85 | // Loop through array - one 86 | // 87 | for i := 0; i < len(arb); i++ { 88 | fmt.Printf("%d\n", arb[i]) 89 | } 90 | // 91 | // Loop through array - two - using range 92 | // 93 | for _, narb := range arb { 94 | // narb is a copy of the element 95 | fmt.Printf("%d\n", narb) 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /chaint1/.gitignore: -------------------------------------------------------------------------------- 1 | chaint1 2 | chaint1.exe 3 | -------------------------------------------------------------------------------- /chaint1/chaint1.go: -------------------------------------------------------------------------------- 1 | /* 2 | Demo chaining 3 | */ 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | ) 9 | 10 | type chainer interface { 11 | FuncA(a int) *chainer 12 | FuncB(b int) *chainer 13 | FuncC(c int) *chainer 14 | } 15 | 16 | type cdata struct { 17 | a, b, c int 18 | } 19 | 20 | func (d *cdata) getA() int { 21 | return d.a 22 | } 23 | 24 | func (d *cdata) getB() int { 25 | return d.b 26 | } 27 | 28 | func (d *cdata) getC() int { 29 | return d.c 30 | } 31 | 32 | func (d *cdata) FuncA(a int) *cdata { 33 | d.a = a 34 | return d 35 | } 36 | 37 | func (d *cdata) FuncB(b int) *cdata { 38 | d.b = b 39 | return d 40 | } 41 | 42 | func (d *cdata) FuncC(c int) *cdata { 43 | d.c = c 44 | return d 45 | } 46 | 47 | func showData(d cdata) { 48 | fmt.Printf("a:%d\n", d.a) 49 | fmt.Printf("b:%d\n", d.b) 50 | fmt.Printf("c:%d\n", d.c) 51 | } 52 | 53 | func main() { 54 | fmt.Println("hi") 55 | // 56 | md := new(cdata) 57 | showData(*md) 58 | md.FuncA(1).FuncB(2).FuncC(3) 59 | showData(*md) 60 | 61 | fmt.Println("bye") 62 | 63 | } 64 | -------------------------------------------------------------------------------- /chanasyn/.gitignore: -------------------------------------------------------------------------------- 1 | chanasyn 2 | chanasyn.exe 3 | -------------------------------------------------------------------------------- /chanasyn/chanasyn.go: -------------------------------------------------------------------------------- 1 | /* 2 | A demonstration of using a buffered channel. Originally from gocourseday3.pdf. 3 | */ 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "time" 9 | ) 10 | 11 | func main() { 12 | fmt.Println("Start ....") 13 | 14 | c := make(chan int, 50) 15 | go func() { 16 | x := <-c 17 | fmt.Println("received", x) 18 | }() 19 | fmt.Println("sending", 10) 20 | c <- 10 21 | fmt.Println("sent", 10) 22 | time.Sleep(10 * time.Second) 23 | // 24 | fmt.Println("End ....") 25 | } 26 | -------------------------------------------------------------------------------- /chanfan01/.gitignore: -------------------------------------------------------------------------------- 1 | chanfan01 2 | chanfan01.exe 3 | -------------------------------------------------------------------------------- /chanfan01/chanfan01.go: -------------------------------------------------------------------------------- 1 | /* 2 | Example code based on Google I/O 2012 concurrency presentation. 3 | */ 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "math/rand" 9 | "time" 10 | ) 11 | 12 | func main() { 13 | c := fanIn(boring("Joe!"), boring("Ann!")) 14 | // Unsequenced 15 | for i := 0; i < 10; i++ { 16 | fmt.Println(<-c) 17 | } 18 | fmt.Println("You're both boring, I'm leaving") 19 | } 20 | 21 | func boring(msg string) <-chan string { 22 | c := make(chan string) 23 | go func() { // Launch from inside function 24 | for i := 0; ; i++ { 25 | c <- fmt.Sprintf("%s %d", msg, i) 26 | time.Sleep(time.Duration(rand.Intn(2e3)) * time.Millisecond) 27 | } 28 | }() 29 | return c // Return the channel to the caller 30 | } 31 | 32 | // Fanin, or multiplexor 33 | func fanIn(input1, input2 <-chan string) <-chan string { 34 | c := make(chan string) 35 | go func() { 36 | for { 37 | c <- <-input1 38 | } 39 | }() 40 | go func() { 41 | for { 42 | c <- <-input2 43 | } 44 | }() 45 | return c 46 | } 47 | -------------------------------------------------------------------------------- /chanfan02/.gitignore: -------------------------------------------------------------------------------- 1 | chanfan02 2 | chanfan02.exe 3 | -------------------------------------------------------------------------------- /chanfan02/chanfan02.go: -------------------------------------------------------------------------------- 1 | /* 2 | Example code based on Google I/O 2012 concurrency presentation. 3 | */ 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "math/rand" 9 | "time" 10 | ) 11 | 12 | type Message struct { 13 | str string 14 | wait chan bool 15 | } 16 | 17 | func main() { 18 | c := fanIn(boring("Joe!"), boring("Ann!")) 19 | // Sequencing restored 20 | for i := 0; i < 10; i++ { 21 | msg1 := <-c 22 | fmt.Println(msg1.str) 23 | msg2 := <-c 24 | fmt.Println(msg2.str) 25 | // 26 | msg1.wait <- true 27 | msg2.wait <- true 28 | } 29 | fmt.Println("You're both boring, I'm leaving") 30 | } 31 | 32 | func boring(msg string) <-chan Message { 33 | c := make(chan Message) 34 | waitForIt := make(chan bool) 35 | go func() { // Launch from inside function 36 | for i := 0; ; i++ { 37 | c <- Message{fmt.Sprintf("%s %d", msg, i), waitForIt} 38 | time.Sleep(time.Duration(rand.Intn(2e3)) * time.Millisecond) 39 | <-waitForIt 40 | } 41 | }() 42 | return c // Return the channel to the caller 43 | } 44 | 45 | // Fanin, or multiplexor 46 | func fanIn(input1, input2 <-chan Message) <-chan Message { 47 | c := make(chan Message) 48 | go func() { 49 | for { 50 | c <- <-input1 51 | } 52 | }() 53 | go func() { 54 | for { 55 | c <- <-input2 56 | } 57 | }() 58 | return c 59 | } 60 | -------------------------------------------------------------------------------- /chanfan03/.gitignore: -------------------------------------------------------------------------------- 1 | chanfan03 2 | chanfan03.exe 3 | -------------------------------------------------------------------------------- /chanfan03/chanfan03.go: -------------------------------------------------------------------------------- 1 | /* 2 | Example code based on Google I/O 2012 concurrency presentation. 3 | */ 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "math/rand" 9 | "time" 10 | ) 11 | 12 | func main() { 13 | c := fanIn(boring("Joe!"), boring("Ann!")) 14 | // Unsequenced 15 | for i := 0; i < 10; i++ { 16 | fmt.Println(<-c) 17 | } 18 | fmt.Println("You're both boring, I'm leaving") 19 | } 20 | 21 | func boring(msg string) <-chan string { 22 | c := make(chan string) 23 | go func() { // Launch from inside function 24 | for i := 0; ; i++ { 25 | c <- fmt.Sprintf("%s %d", msg, i) 26 | time.Sleep(time.Duration(rand.Intn(2e3)) * time.Millisecond) 27 | } 28 | }() 29 | return c // Return the channel to the caller 30 | } 31 | 32 | // Fanin, or multiplexor 33 | func fanIn(input1, input2 <-chan string) <-chan string { 34 | c := make(chan string) 35 | // Single go routine 36 | go func() { 37 | for { 38 | select { 39 | case s := <-input1: 40 | c <- s 41 | case s := <-input2: 42 | c <- s 43 | } 44 | } 45 | }() 46 | return c 47 | } 48 | -------------------------------------------------------------------------------- /chanfan04/.gitignore: -------------------------------------------------------------------------------- 1 | chanfan04 2 | chanfan04.exe 3 | -------------------------------------------------------------------------------- /chanfan04/chanfan04.go: -------------------------------------------------------------------------------- 1 | /* 2 | Example code based on Google I/O 2012 concurrency presentation. 3 | */ 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "math/rand" 9 | "time" 10 | ) 11 | 12 | func main() { 13 | c := boring("Joe!") 14 | // 15 | for { 16 | // Timeout each message 17 | select { 18 | case s := <-c: 19 | fmt.Println(s) 20 | case <-time.After(1 * time.Second): 21 | fmt.Println("You're too slow, I'm leaving") 22 | return 23 | } 24 | } 25 | } 26 | 27 | func boring(msg string) <-chan string { 28 | c := make(chan string) 29 | go func() { // Launch from inside function 30 | for i := 0; ; i++ { 31 | c <- fmt.Sprintf("%s %d", msg, i) 32 | time.Sleep(time.Duration(rand.Intn(2e3)) * time.Millisecond) 33 | } 34 | }() 35 | return c // Return the channel to the caller 36 | } 37 | -------------------------------------------------------------------------------- /chanfan05/.gitignore: -------------------------------------------------------------------------------- 1 | chanfan05 2 | chanfan05.exe 3 | -------------------------------------------------------------------------------- /chanfan05/chanfan05.go: -------------------------------------------------------------------------------- 1 | /* 2 | Example code based on Google I/O 2012 concurrency presentation. 3 | */ 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "math/rand" 9 | "time" 10 | ) 11 | 12 | func main() { 13 | c := boring("Joe!") 14 | // Timeout entire loop 15 | timeout := time.After(5 * time.Second) 16 | for { 17 | select { 18 | case s := <-c: 19 | fmt.Println(s) 20 | case <-timeout: 21 | fmt.Println("You talk too much, I'm leaving") 22 | return 23 | } 24 | } 25 | } 26 | 27 | func boring(msg string) <-chan string { 28 | c := make(chan string) 29 | go func() { // Launch from inside function 30 | for i := 0; ; i++ { 31 | c <- fmt.Sprintf("%s %d", msg, i) 32 | time.Sleep(time.Duration(rand.Intn(2e3)) * time.Millisecond) 33 | } 34 | }() 35 | return c // Return the channel to the caller 36 | } 37 | -------------------------------------------------------------------------------- /chanfan06/.gitignore: -------------------------------------------------------------------------------- 1 | chanfan06 2 | chanfan06.exe 3 | -------------------------------------------------------------------------------- /chanfan06/chanfan06.go: -------------------------------------------------------------------------------- 1 | /* 2 | Example code based on Google I/O 2012 concurrency presentation. 3 | */ 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "math/rand" 9 | "time" 10 | ) 11 | 12 | func main() { 13 | quit := make(chan bool) 14 | c := boring("Joe!", quit) 15 | // Joe can olny talk so much, and then is told to quit. 16 | for i := rand.Intn(10); i >= 0; i-- { 17 | fmt.Println(<-c) 18 | } 19 | quit <- true 20 | time.Sleep(100 * time.Millisecond) 21 | } 22 | 23 | func boring(msg string, quit chan bool) <-chan string { 24 | c := make(chan string) 25 | go func() { // Launch from inside function 26 | i := 1 27 | for { 28 | select { 29 | case c <- fmt.Sprintf("%s %d", msg, i): 30 | i++ 31 | case <-quit: 32 | fmt.Println("Stopping") 33 | return 34 | } 35 | } 36 | }() 37 | return c // Return the channel to the caller 38 | } 39 | -------------------------------------------------------------------------------- /chanfan07/.gitignore: -------------------------------------------------------------------------------- 1 | chanfan07 2 | chanfan07.exe 3 | -------------------------------------------------------------------------------- /chanfan07/chanfan07.go: -------------------------------------------------------------------------------- 1 | /* 2 | Example code based on Google I/O 2012 concurrency presentation. 3 | */ 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "math/rand" 9 | ) 10 | 11 | func main() { 12 | quit := make(chan string) 13 | c := boring("Joe!", quit) 14 | // Joe can olny talk so much, and then is told to quit. 15 | for i := rand.Intn(10); i >= 0; i-- { 16 | fmt.Println(<-c) 17 | } 18 | quit <- "Bye!" 19 | fmt.Printf("Joe says: %s\n", <-quit) 20 | } 21 | 22 | func boring(msg string, quit chan string) <-chan string { 23 | c := make(chan string) 24 | go func() { // Launch from inside function 25 | i := 1 26 | for { 27 | select { 28 | case c <- fmt.Sprintf("%s %d", msg, i): 29 | i++ 30 | case <-quit: 31 | fmt.Println("Cleanup complete") 32 | quit <- "See ya!" 33 | return 34 | } 35 | } 36 | }() 37 | return c // Return the channel to the caller 38 | } 39 | -------------------------------------------------------------------------------- /chanfan08/.gitignore: -------------------------------------------------------------------------------- 1 | chanfan08 2 | chanfan08.exe 3 | -------------------------------------------------------------------------------- /chanfan08/chanfan08.go: -------------------------------------------------------------------------------- 1 | /* 2 | Example code based on Google I/O 2012 concurrency presentation. 3 | */ 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | ) 9 | 10 | // Daisy chain 11 | 12 | func f(left, right chan int) { 13 | left <- 1 + <-right 14 | } 15 | 16 | func main() { 17 | const n = 10000 18 | leftmost := make(chan int) 19 | right := leftmost 20 | left := leftmost 21 | for i := 0; i < n; i++ { 22 | right = make(chan int) 23 | go f(left, right) 24 | left = right 25 | } 26 | go func(c chan int) { c <- 1 }(right) 27 | fmt.Println(<-leftmost) 28 | } 29 | -------------------------------------------------------------------------------- /chanfanout/.gitignore: -------------------------------------------------------------------------------- 1 | chanfanout 2 | chanfanout.exe 3 | -------------------------------------------------------------------------------- /chanfanout/chanfanout.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | // Modified example from: 8 | // http://stackoverflow.com/questions/16930251/go-one-producer-many-consumers 9 | 10 | func fanOut(ch <-chan int, size, lag int) []chan int { 11 | cs := make([]chan int, size) 12 | for i, _ := range cs { 13 | // The size of the channels buffer controls how far behind the recievers 14 | // of the fanOut channels can lag the other channels. 15 | cs[i] = make(chan int, lag) 16 | } 17 | go func() { 18 | for i := range ch { 19 | for _, c := range cs { 20 | c <- i 21 | } 22 | } 23 | for _, c := range cs { 24 | // close all our fanOut channels when the input channel is exhausted. 25 | close(c) 26 | } 27 | }() 28 | return cs 29 | } 30 | 31 | func main() { 32 | fmt.Println("hi") 33 | const ( 34 | chsz = 1 35 | sz = 1 36 | lag = 1 37 | ) 38 | ch := make(chan int, chsz) 39 | co := fanOut(ch, sz, lag) 40 | fmt.Println("CO", co) 41 | fmt.Println("bye") 42 | } 43 | -------------------------------------------------------------------------------- /chanfanout2/.gitignore: -------------------------------------------------------------------------------- 1 | chanfanout2 2 | chanfanout2.exe 3 | -------------------------------------------------------------------------------- /chanfanout2/chanfanout2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | // Modified example from: 9 | // http://stackoverflow.com/questions/16930251/go-one-producer-many-consumers 10 | // and the referenced implementation. 11 | 12 | func producer(iters int) <-chan int { 13 | c := make(chan int) 14 | go func() { 15 | for i := 0; i < iters; i++ { 16 | c <- i 17 | time.Sleep(1 * time.Second) 18 | } 19 | close(c) 20 | }() 21 | return c 22 | } 23 | 24 | func consumer(cin <-chan int) { 25 | for i := range cin { 26 | fmt.Println(i) 27 | } 28 | } 29 | 30 | func fanOut(ch <-chan int, size, lag int) []chan int { 31 | cs := make([]chan int, size) 32 | for i, _ := range cs { 33 | // The size of the channels buffer controls how far behind the recievers 34 | // of the fanOut channels can lag the other channels. 35 | cs[i] = make(chan int, lag) 36 | } 37 | go func() { 38 | for i := range ch { 39 | for _, c := range cs { 40 | c <- i 41 | } 42 | } 43 | for _, c := range cs { 44 | // close all our fanOut channels when the input channel is exhausted. 45 | close(c) 46 | } 47 | }() 48 | return cs 49 | } 50 | 51 | func fanOutUnbuffered(ch <-chan int, size int) []chan int { 52 | cs := make([]chan int, size) 53 | for i, _ := range cs { 54 | // The size of the channels buffer controls how far behind the recievers 55 | // of the fanOut channels can lag the other channels. 56 | cs[i] = make(chan int) 57 | } 58 | go func() { 59 | for i := range ch { 60 | for _, c := range cs { 61 | c <- i 62 | } 63 | } 64 | for _, c := range cs { 65 | // close all our fanOut channels when the input channel is exhausted. 66 | close(c) 67 | } 68 | }() 69 | return cs 70 | } 71 | 72 | func main() { 73 | c := producer(10) 74 | chans := fanOutUnbuffered(c, 3) 75 | go consumer(chans[0]) 76 | go consumer(chans[1]) 77 | consumer(chans[2]) 78 | } 79 | -------------------------------------------------------------------------------- /chanloop/.gitignore: -------------------------------------------------------------------------------- 1 | chanloop 2 | chanloop.exe 3 | -------------------------------------------------------------------------------- /chanloop/chanloop.go: -------------------------------------------------------------------------------- 1 | /* 2 | Loop and receive values from a buffered channel. 3 | */ 4 | package main 5 | 6 | // 7 | import ( 8 | "fmt" 9 | // "time" 10 | ) 11 | 12 | // 13 | func runner(inc chan int, wc chan bool) { 14 | fmt.Println("runner starting") 15 | dobreak := false 16 | for { 17 | if dobreak { 18 | break 19 | } 20 | select { 21 | case ival := <-inc: 22 | fmt.Println("runner got value", ival) 23 | default: 24 | fmt.Println("runner found nothing") 25 | dobreak = true 26 | } 27 | } 28 | // 29 | wc <- true // we are done 30 | fmt.Println("runner ending") 31 | } 32 | 33 | // 34 | func main() { 35 | fmt.Println("Start ....") 36 | // 37 | isc := make(chan int, 3) 38 | isc <- 1 39 | isc <- 2 40 | isc <- 3 41 | // 42 | fmt.Println("Three are queued ....") 43 | waitChan := make(chan bool) 44 | go runner(isc, waitChan) 45 | fmt.Println("Starting wait ....") 46 | doneFlag := <-waitChan 47 | fmt.Println("Done", doneFlag) 48 | // 49 | fmt.Println("End ....") 50 | } 51 | -------------------------------------------------------------------------------- /channelLock/.gitignore: -------------------------------------------------------------------------------- 1 | channelLock 2 | channelLock.exe 3 | 4 | -------------------------------------------------------------------------------- /channelLock/fastQuit/.gitignore: -------------------------------------------------------------------------------- 1 | fastQuit 2 | fastQuit.exe 3 | -------------------------------------------------------------------------------- /chanokt/.gitignore: -------------------------------------------------------------------------------- 1 | chanokt 2 | chanokt.exe 3 | -------------------------------------------------------------------------------- /chanokt/chanokt.go: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | */ 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | ) 9 | 10 | func main() { 11 | fmt.Println("starting") 12 | // 13 | c := make(chan int, 1) // A small buffer 14 | fmt.Printf("Print Test: %v\n", c) 15 | fmt.Printf("Length01: %d\n", len(c)) // Ignore races here :-) 16 | c <- 1 17 | fmt.Printf("Length02: %d\n", len(c)) // And here 18 | _ = <- c // clear 19 | 20 | // Test the if comma ok way 21 | c <- 2 22 | close(c) // the test 23 | // This receive works, even with the closed channel 24 | val, ok := <- c 25 | if ok { 26 | fmt.Printf("OK2, len, val: %d , %d\n", len(c), val) // 27 | } else { 28 | fmt.Printf("NOTOK2, len, val: %d , %d\n", len(c), val) // 29 | } 30 | // This receive fails 31 | val, ok = <- c 32 | if ok { 33 | fmt.Printf("OK3, len, val: %d , %d\n", len(c), val) // 34 | } else { 35 | fmt.Printf("NOTOK3, len, val: %d , %d\n", len(c), val) // 36 | } 37 | // 38 | // close(c) // 2nd time: panic 39 | 40 | 41 | // Test the range way 42 | c2 := make(chan int, 1) // A small buffer 43 | fmt.Printf("Print Test2: %v\n", c2) 44 | c2 <- 3 45 | close(c2) // the test 46 | // 47 | for v := range c2 { 48 | fmt.Printf("RANGE1, v: %d\n", v) // 49 | } 50 | fmt.Println("=============") 51 | for v2 := range c2 { 52 | fmt.Printf("RANGE2, v2: %d\n", v2) // Does not run 53 | } 54 | // 55 | fmt.Println("ending") 56 | 57 | // Test the if comma ok way, no close 58 | c3 := make(chan int, 1) // A small buffer 59 | fmt.Printf("Print Test3: %v\n", c3) 60 | c3 <- 4 61 | // no close() here 62 | // This receive works, of course. 63 | val, ok = <- c3 64 | if ok { 65 | fmt.Printf("OK4, len, val: %d , %d\n", len(c3), val) // 66 | } else { 67 | fmt.Printf("NOTOK4, len, val: %d , %d\n", len(c3), val) // 68 | } 69 | // This panics 70 | /* 71 | val4, ok4 := <- c3 // -> fatal error: all goroutines are asleep - deadlock! 72 | if ok4 { 73 | fmt.Printf("OK4, len, val: %d , %d\n", len(c3), val4) // 74 | } else { 75 | fmt.Printf("NOTOK4, len, val: %d , %d\n", len(c3), val4) // 76 | } 77 | */ 78 | // Try this instead. Also panics. 79 | /* 80 | fmt.Println("=============") 81 | for v3 := range c3 { // -> fatal error: all goroutines are asleep - deadlock! 82 | fmt.Printf("RANGE3, v3: %d\n", v3) // 83 | } 84 | */ 85 | 86 | } 87 | 88 | -------------------------------------------------------------------------------- /chanrange/.gitignore: -------------------------------------------------------------------------------- 1 | chanrange 2 | chanrange.exe 3 | -------------------------------------------------------------------------------- /chanrange/chanrange.go: -------------------------------------------------------------------------------- 1 | /* 2 | Loop and receive values from a buffered channel using range. 3 | */ 4 | package main 5 | 6 | // 7 | import ( 8 | "fmt" 9 | ) 10 | 11 | // 12 | func runner(inc chan int, wc chan bool) { 13 | fmt.Println("runner starting") 14 | for ival := range inc { 15 | fmt.Println("runner got value", ival) 16 | // If we do not break here, we get at runtime: 17 | // throw: all goroutines are asleep - deadlock! 18 | if ival == 3 { 19 | break 20 | } 21 | } 22 | wc <- true // we are done 23 | fmt.Println("runner ending") 24 | } 25 | 26 | // 27 | func main() { 28 | fmt.Println("Start ....") 29 | // 30 | isc := make(chan int, 3) 31 | isc <- 1 32 | isc <- 2 33 | isc <- 3 34 | // 35 | fmt.Println("Three are queued ....") 36 | waitChan := make(chan bool) 37 | go runner(isc, waitChan) 38 | fmt.Println("Starting wait ....") 39 | doneFlag := <-waitChan 40 | fmt.Println("Done", doneFlag) 41 | // 42 | fmt.Println("End ....") 43 | } 44 | -------------------------------------------------------------------------------- /chanshunt/.gitignore: -------------------------------------------------------------------------------- 1 | chanshunt 2 | chanshunt.exe 3 | -------------------------------------------------------------------------------- /chanshunt/chanshunt.go: -------------------------------------------------------------------------------- 1 | /* 2 | An example taken from: https://groups.google.com/forum/?fromgroups#!topic/golang-nuts/VdmoZ59jjoE 3 | */ 4 | package main 5 | 6 | import "fmt" 7 | 8 | // 9 | // See: 10 | // https://groups.google.com/forum/?fromgroups#!topic/golang-nuts/VdmoZ59jjoE 11 | // http://play.golang.org/p/ZJamJZgeEK 12 | // 13 | // A channel shunt (or shovel). 14 | // 15 | func shunt(input <-chan int, output chan<- int) { 16 | var ( 17 | i int 18 | ok bool 19 | in = input 20 | out chan<- int 21 | ) 22 | for { 23 | select { 24 | case i, ok = <-in: 25 | if !ok { 26 | close(output) 27 | fmt.Println("done") 28 | return 29 | } 30 | fmt.Println("shunt in", i) 31 | in = nil 32 | out = output 33 | case out <- i: 34 | fmt.Println("shunt out", i) 35 | in = input 36 | out = nil 37 | } 38 | } 39 | 40 | } 41 | 42 | func main() { 43 | input := make(chan int, 100) 44 | go func() { // Simulate a sender to input in another part of the program 45 | for i := 0; i < 1000; i++ { 46 | input <- i 47 | } 48 | close(input) 49 | }() 50 | 51 | acc := make(chan int, 10) // accumulator channel 52 | go shunt(input, acc) 53 | for i := range acc { 54 | fmt.Println("acc read:", i) 55 | } 56 | fmt.Println("exit") 57 | } 58 | -------------------------------------------------------------------------------- /chanshunt_2/.gitignore: -------------------------------------------------------------------------------- 1 | chanshunt_2 2 | chanshunt_2.exe 3 | -------------------------------------------------------------------------------- /chansvr1/.gitignore: -------------------------------------------------------------------------------- 1 | chansvr1 2 | chansvr1.exe 3 | -------------------------------------------------------------------------------- /chansvr1/chansvr1.go: -------------------------------------------------------------------------------- 1 | /* 2 | A simple server using channels. Another example from the gocourseday3.pdf. 3 | */ 4 | package main 5 | 6 | import "fmt" 7 | 8 | // 9 | // This example works as presented in the PDF. This is mostly cut and 10 | // paste. 11 | // 12 | // The request. 13 | // 14 | type request struct { 15 | a, b int 16 | replyc chan int 17 | } 18 | 19 | // 20 | // Operation type definition. 21 | // 22 | type binOp func(a, b int) int 23 | 24 | // 25 | // The low level 'runner'. 26 | // 27 | func run(op binOp, req *request) { 28 | req.replyc <- op(req.a, req.b) 29 | } 30 | 31 | // 32 | // The server logic. 33 | // 34 | func server(op binOp, service chan *request) { 35 | for { 36 | req := <-service // requests arrive here 37 | go run(op, req) // don't wait for op 38 | } 39 | } 40 | 41 | // 42 | // Server startup. 43 | // 44 | func startServer(op binOp) chan *request { 45 | req := make(chan *request) 46 | go server(op, req) 47 | return req 48 | } 49 | 50 | /* 51 | Print requests nicely. 52 | */ 53 | func (r *request) String() string { 54 | return fmt.Sprintf("%d+%d=%d", r.a, r.b, <-r.replyc) 55 | } 56 | 57 | // 58 | // Mainline. 59 | // 60 | func main() { 61 | fmt.Println("Start...") 62 | // Server start. 63 | var adderChan = startServer(func(a, b int) int { return a + b }) 64 | // Create some requests 65 | req1 := &request{7, 8, make(chan int)} 66 | req2 := &request{17, 18, make(chan int)} 67 | // Send the requests 68 | adderChan <- req1 69 | adderChan <- req2 70 | // Get and show reply. 71 | fmt.Println(req2, req1) 72 | // 73 | fmt.Println("End...") 74 | } 75 | -------------------------------------------------------------------------------- /chansvr2/.gitignore: -------------------------------------------------------------------------------- 1 | chansvr2 2 | chansvr2.exe 3 | -------------------------------------------------------------------------------- /chansvr2/chansvr2.go: -------------------------------------------------------------------------------- 1 | /* 2 | A simple server using channels, with client controlled shutdown. 3 | */ 4 | package main 5 | 6 | import "fmt" 7 | 8 | // 9 | // Another example from the gocourseday3.pdf. 10 | // 11 | // This example works as presented in the PDF. This is mostly cut and 12 | // paste. This adds to the previous example, but shows client controlled 13 | // shutdown of the server. 14 | // 15 | // The request. 16 | // 17 | type request struct { 18 | a, b int 19 | replyc chan int 20 | } 21 | 22 | // 23 | // Operation type definition. 24 | // 25 | type binOp func(a, b int) int 26 | 27 | // 28 | // The low level 'runner'. 29 | // 30 | func run(op binOp, req *request) { 31 | req.replyc <- op(req.a, req.b) 32 | } 33 | 34 | // 35 | // The server logic. 36 | // 37 | func server(op binOp, service chan *request, quit chan bool) { 38 | for { 39 | select { 40 | case req := <-service: 41 | go run(op, req) // don't wait for it 42 | case <-quit: 43 | fmt.Println("OK, serever done") 44 | return 45 | } 46 | } 47 | } 48 | 49 | // 50 | // Server startup. 51 | // 52 | func startServer(op binOp) (chan *request, chan bool) { 53 | service := make(chan *request) 54 | quit := make(chan bool) 55 | go server(op, service, quit) 56 | return service, quit 57 | } 58 | 59 | // 60 | // Print requests nicely. 61 | // 62 | func (r *request) String() string { 63 | return fmt.Sprintf("%d+%d=%d", r.a, r.b, <-r.replyc) 64 | } 65 | 66 | // 67 | // Mainline. 68 | // 69 | func main() { 70 | fmt.Println("Start...") 71 | // Server start. 72 | var adderChan, quitChan = startServer(func(a, b int) int { return a + b }) 73 | // Create some requests 74 | req1 := &request{7, 8, make(chan int)} 75 | req2 := &request{17, 18, make(chan int)} 76 | // Send the requests 77 | adderChan <- req1 78 | adderChan <- req2 79 | // Get and show reply. 80 | fmt.Println(req2, req1) 81 | // 82 | quitChan <- true 83 | // 84 | fmt.Println("End...") 85 | } 86 | -------------------------------------------------------------------------------- /chansyn/.gitignore: -------------------------------------------------------------------------------- 1 | chansyn 2 | chansyn.exe 3 | -------------------------------------------------------------------------------- /chansyn/chansyn.go: -------------------------------------------------------------------------------- 1 | /* 2 | Example of using an unbuffered channel, based on gocourseday3.pdf. 3 | */ 4 | package main 5 | 6 | // 7 | import ( 8 | "fmt" 9 | "time" 10 | ) 11 | 12 | // 13 | // gocourseday3.pdf - simple synchronous channel example. 14 | // Slightly embellished. 15 | // 16 | func main() { 17 | fmt.Println("Start ....") 18 | // 19 | syn_chan := make(chan int) // Synchronous: no buffering specified 20 | done_chan := make(chan bool) // Also synchronous 21 | go func() { 22 | time.Sleep(2 * 1e9) 23 | fmt.Println("receiver is up") 24 | x := <-syn_chan // Receive. Will block until data received 25 | fmt.Println("starting work, received", x) 26 | tw := time.Duration(x * 1e9) 27 | time.Sleep(tw) // Simulate work 28 | fmt.Println("work complete") 29 | done_chan <- true // Signal done 30 | }() 31 | // 32 | fmt.Println("sending", 5) 33 | syn_chan <- 5 // Send. Will block until a receive complete 34 | fmt.Println("sent", 5) 35 | fmt.Println("waiting for complete work") 36 | done_flag := <-done_chan 37 | fmt.Println("done is:", done_flag) 38 | // 39 | fmt.Println("End ....") 40 | } 41 | -------------------------------------------------------------------------------- /chantest/.gitignore: -------------------------------------------------------------------------------- 1 | chantest 2 | chantest.exe 3 | -------------------------------------------------------------------------------- /chantest/chantest.go: -------------------------------------------------------------------------------- 1 | /* 2 | A demonstration of blocking when using an unbuffered channel. 3 | */ 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "time" 9 | ) 10 | 11 | func worker(c chan int) { 12 | fmt.Println("worker starts ...") 13 | var x int = -1 14 | var ok bool = false 15 | time.Sleep(5 * 1e9) 16 | select { 17 | case x = <-c: 18 | ok = true 19 | default: 20 | ok = false 21 | } 22 | fmt.Printf("received %d %t\n", x, ok) 23 | } 24 | 25 | // 26 | // Tests to see if a channel will block. 27 | // 28 | func main() { 29 | fmt.Println("Start ....") 30 | fmt.Println("===========") 31 | // 32 | var tosend int = 1 33 | c := make(chan int) 34 | go func() { 35 | time.Sleep(5 * 1e9) 36 | x := <-c 37 | fmt.Println("received", x) 38 | }() 39 | // 40 | fmt.Println("sending", tosend) 41 | c <- tosend 42 | fmt.Println("sent1", tosend) 43 | // 44 | fmt.Println("===========") 45 | tosend = 2 46 | unbuf := make(chan int) 47 | go worker(unbuf) // 48 | unbuf <- tosend 49 | fmt.Println("sent2", tosend) 50 | // 51 | fmt.Println("===========") 52 | tosend = 3 53 | buf := make(chan int, 1) 54 | go worker(buf) // 55 | var ok bool = false 56 | select { 57 | case buf <- tosend: 58 | ok = true 59 | default: 60 | ok = false 61 | } 62 | fmt.Println("sent3", tosend, ok) 63 | time.Sleep(6 * 1e9) 64 | // 65 | fmt.Println("End ....") 66 | } 67 | -------------------------------------------------------------------------------- /charshow/.gitignore: -------------------------------------------------------------------------------- 1 | charshow 2 | charshow.exe 3 | -------------------------------------------------------------------------------- /charshow/charshow.go: -------------------------------------------------------------------------------- 1 | /* 2 | Playing with UTF8 strings. 3 | */ 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "unicode/utf8" 9 | ) 10 | 11 | func hrune(r rune) string { 12 | return fmt.Sprintf("%08x", r) 13 | } 14 | 15 | func main() { 16 | fmt.Println("hi") 17 | s := "𐒁̸" 18 | fmt.Println(s, len(s), utf8.RuneCountInString(s)) 19 | s = "汉" 20 | fmt.Println(s, len(s), utf8.RuneCountInString(s)) 21 | s = "𐒁̸汉" 22 | fmt.Println(s, len(s), utf8.RuneCountInString(s)) 23 | // 24 | for i, r := range s { 25 | fmt.Println(i, hrune(r), " ", string(r), utf8.RuneLen(r)) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /dateshow/.gitignore: -------------------------------------------------------------------------------- 1 | dateshow 2 | dateshow.exe 3 | -------------------------------------------------------------------------------- /dateshow/dateshow.go: -------------------------------------------------------------------------------- 1 | /* 2 | Show oddities about date formatting. 3 | */ 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "time" 9 | ) 10 | 11 | // Date formatting may show seemingly incorrect values when using a 12 | // local Location. 13 | func main() { 14 | fmt.Println("Start...") 15 | // 16 | l := "01/02/06" // Layout string 17 | d := "08/26/12" // Date string 18 | n, err := time.Parse(l, d[:8]) // Get time.Time 19 | if err != nil { 20 | panic(err) 21 | } 22 | fmt.Println("time.Time1:", n) // UTC, mm/dd/yy is correct 23 | // 24 | i := n.Unix() // Seconds 25 | nd := time.Unix(int64(i), 0) // Has local Location, here at present: EDT 26 | // For this example may show 08/25/12. 27 | fmt.Println("time.Time2:", nd) // Local, e.g. EST, mm/dd/yy may be incorrect 28 | // 29 | nu := nd.UTC() // Force to UTC 30 | fmt.Println("time.Time3:", nu) // UTC again, mm/dd/yy is correct 31 | // 32 | fmt.Println("End...") 33 | } 34 | -------------------------------------------------------------------------------- /defer/.gitignore: -------------------------------------------------------------------------------- 1 | defer 2 | defer.exe 3 | -------------------------------------------------------------------------------- /defer/defer.go: -------------------------------------------------------------------------------- 1 | /* 2 | A contrived example of using defer. 3 | */ 4 | package main 5 | 6 | import ( 7 | "fmt" // 8 | ) 9 | 10 | /* 11 | Defers operate LIFO 12 | */ 13 | func printBack() { 14 | for i := 1; i <= 5; i++ { 15 | defer fmt.Printf("%d ", i) 16 | } 17 | } 18 | 19 | /* 20 | Using defer for tracing. 21 | */ 22 | func trace(s string) string { 23 | fmt.Println("entering: ", s) 24 | return s 25 | } 26 | 27 | // 28 | func un(s string) { 29 | fmt.Println("leaving: ", s) 30 | } 31 | func inner() { 32 | defer un(trace("inner")) 33 | fmt.Println("in inner()") 34 | } 35 | func outer() { 36 | defer un(trace("outer")) 37 | fmt.Println("in outer() before call") 38 | inner() 39 | fmt.Println("in outer() after call") 40 | } 41 | 42 | func main() { 43 | fmt.Println("Start...") 44 | printBack() 45 | // 46 | fmt.Println() 47 | outer() 48 | // 49 | fmt.Println("End...") 50 | } 51 | -------------------------------------------------------------------------------- /demo_templates/call/.gitignore: -------------------------------------------------------------------------------- 1 | call 2 | call.exe 3 | -------------------------------------------------------------------------------- /demo_templates/call/call.go: -------------------------------------------------------------------------------- 1 | /* 2 | From: 3 | https://github.com/golang/go/issues/10653 4 | https://play.golang.org/p/Ka8bN3_V1f 5 | */ 6 | package main 7 | 8 | import ( 9 | "os" 10 | "text/template" 11 | ) 12 | 13 | type TestStructA struct { 14 | Test func(string) string 15 | } 16 | 17 | func test(s string) string { 18 | return "Test A Says " + s + "\n" 19 | } 20 | 21 | type TestStructB struct { 22 | } 23 | 24 | func (self TestStructB) Test() func(string) string { 25 | return func(s string) string { return "Test B Says " + s + "\n" } 26 | } 27 | 28 | // DOES NOT WORK 29 | type TestStructC struct { 30 | } 31 | 32 | func (self TestStructC) Test(s string) string { 33 | return "Test C Says " + s + "\n" 34 | } 35 | 36 | func noCall() { 37 | tempStr := "{{.Test \"hi\"}}" // NB: no 'call' function used 38 | t := template.Must(template.New("test_temp2").Parse(tempStr)) 39 | testC := TestStructC{} 40 | err := t.Execute(os.Stdout, testC) 41 | if err != nil { 42 | panic(err) 43 | } 44 | } 45 | 46 | func main() { 47 | tempStr := "{{call .Test \"hi\"}}" 48 | t := template.Must(template.New("test_temp").Parse(tempStr)) 49 | 50 | testA := TestStructA{Test: test} 51 | err := t.Execute(os.Stdout, testA) 52 | if err != nil { 53 | panic(err) 54 | } 55 | 56 | testB := TestStructB{} 57 | err = t.Execute(os.Stdout, testB) 58 | if err != nil { 59 | panic(err) 60 | } 61 | 62 | noCall() // other way to do the 'does not work' part below 63 | 64 | // DOES NOT WORK 65 | testC := TestStructC{} 66 | err = t.Execute(os.Stdout, testC) 67 | if err != nil { 68 | panic(err) 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /demo_templates/conditions/.gitignore: -------------------------------------------------------------------------------- 1 | conditions 2 | conditions.exe 3 | -------------------------------------------------------------------------------- /demo_templates/conditions/conditions.go: -------------------------------------------------------------------------------- 1 | /* 2 | Example from: 3 | https://astaxie.gitbooks.io/build-web-application-with-golang/en/07.4.html 4 | */ 5 | 6 | package main 7 | 8 | import ( 9 | "os" 10 | "text/template" 11 | ) 12 | 13 | func main() { 14 | tEmpty := template.New("template test") 15 | tEmpty = template.Must(tEmpty.Parse("Empty pipeline if demo: {{if ``}} will not be outputted. {{end}}\n")) 16 | tEmpty.Execute(os.Stdout, nil) 17 | 18 | tWithValue := template.New("template test") 19 | tWithValue = template.Must(tWithValue.Parse("Not empty pipeline if demo: {{if `anything`}} will be outputted. {{end}}\n")) 20 | tWithValue.Execute(os.Stdout, nil) 21 | 22 | tIfElse := template.New("template test") 23 | tIfElse = template.Must(tIfElse.Parse("if-else demo: {{if `anything`}} if part {{else}} else part.{{end}}\n")) 24 | tIfElse.Execute(os.Stdout, nil) 25 | } 26 | -------------------------------------------------------------------------------- /demo_templates/functions/.gitignore: -------------------------------------------------------------------------------- 1 | functions 2 | functions.exe 3 | -------------------------------------------------------------------------------- /demo_templates/functions/functions.go: -------------------------------------------------------------------------------- 1 | /* 2 | Example from: 3 | https://astaxie.gitbooks.io/build-web-application-with-golang/en/07.4.html 4 | */ 5 | 6 | package main 7 | 8 | import ( 9 | "fmt" 10 | "html/template" 11 | "os" 12 | "strings" 13 | ) 14 | 15 | type Friend struct { 16 | Fname string 17 | } 18 | 19 | type Person struct { 20 | UserName string 21 | Emails []string 22 | Friends []*Friend 23 | } 24 | 25 | func EmailDealWith(args ...interface{}) string { 26 | ok := false 27 | var s string 28 | if len(args) == 1 { 29 | s, ok = args[0].(string) 30 | } 31 | if !ok { 32 | s = fmt.Sprint(args...) 33 | } 34 | // find the @ symbol 35 | substrs := strings.Split(s, "@") 36 | if len(substrs) != 2 { 37 | return s 38 | } 39 | // replace the @ by " at " 40 | return (substrs[0] + " at " + substrs[1]) 41 | } 42 | 43 | func main() { 44 | f1 := Friend{Fname: "Chris"} 45 | f2 := Friend{Fname: "George"} 46 | t := template.New("fieldname example") 47 | t = t.Funcs(template.FuncMap{"emailDeal": EmailDealWith}) 48 | t, _ = t.Parse(`hello {{.UserName}}! 49 | {{range .Emails}} 50 | an emails {{.|emailDeal}} 51 | {{end}} 52 | {{with .Friends}} 53 | {{range .}} 54 | my friend name is {{.Fname}} 55 | {{end}} 56 | {{end}} 57 | `) 58 | p := Person{UserName: "Guy", 59 | Emails: []string{"guy@gmallard.com", "allard.guy.m@gmail.com"}, 60 | Friends: []*Friend{&f1, &f2}} 61 | t.Execute(os.Stdout, p) 62 | } 63 | -------------------------------------------------------------------------------- /demo_templates/golangtutorials/fieldname/.gitignore: -------------------------------------------------------------------------------- 1 | fieldname 2 | fieldname.exe 3 | -------------------------------------------------------------------------------- /demo_templates/golangtutorials/fieldname/fieldname.go: -------------------------------------------------------------------------------- 1 | /* 2 | Modified From: http://golangtutorials.blogspot.com/2011/06/go-templates.html 3 | */ 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "os" 9 | "text/template" 10 | ) 11 | 12 | type Person struct { 13 | Name string 14 | AgeField string // OK 15 | } 16 | 17 | func main() { 18 | p := Person{Name: "Mary", AgeField: "31"} 19 | 20 | t := template.New("nonexported template demo") 21 | t, _ = t.Parse("hello1 {{.Name}}! ") 22 | err := t.Execute(os.Stdout, p) 23 | if err != nil { 24 | fmt.Println("There was an error:", err) 25 | } 26 | // 27 | t, _ = t.Parse("Age {{.AgeField}}!\n") 28 | err = t.Execute(os.Stdout, p) 29 | if err != nil { 30 | fmt.Println("There was an error:", err) 31 | } 32 | // 33 | t, _ = t.Parse("hello2 {{.Name}}! Age {{.AgeField}}!\n") 34 | err = t.Execute(os.Stdout, p) 35 | if err != nil { 36 | fmt.Println("There was an error:", err) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /demo_templates/golangtutorials/printf/.gitignore: -------------------------------------------------------------------------------- 1 | printf 2 | printf.exe 3 | -------------------------------------------------------------------------------- /demo_templates/golangtutorials/printf/printf.go: -------------------------------------------------------------------------------- 1 | /* 2 | From: 3 | http://golangtutorials.blogspot.com/2011/10/go-templates-part-2.html 4 | */ 5 | package main 6 | 7 | import ( 8 | "os" 9 | "text/template" 10 | ) 11 | 12 | func main() { 13 | t := template.New("test") 14 | t = template.Must(t.Parse("{{with $x := `hello`}}{{printf `%s %s` $x `Mary`}}{{end}}!\n")) 15 | t.Execute(os.Stdout, nil) 16 | } 17 | -------------------------------------------------------------------------------- /demo_templates/golangtutorials/revquotes/.gitignore: -------------------------------------------------------------------------------- 1 | revquotes 2 | revquotes.exe 3 | -------------------------------------------------------------------------------- /demo_templates/golangtutorials/revquotes/revquotes.go: -------------------------------------------------------------------------------- 1 | /* 2 | From: 3 | http://golangtutorials.blogspot.com/2011/10/go-templates-part-2.html 4 | */ 5 | package main 6 | 7 | import ( 8 | "os" 9 | "text/template" 10 | ) 11 | 12 | func main() { 13 | t := template.New("template test") 14 | t = template.Must(t.Parse("This is just static text. \n{{\"This is pipeline data - because it is evaluated within the double braces.\"}} {{`So is this, but within reverse quotes.`}}\n")) 15 | t.Execute(os.Stdout, nil) 16 | } 17 | -------------------------------------------------------------------------------- /demo_templates/golangtutorials/tvars/.gitignore: -------------------------------------------------------------------------------- 1 | tvars 2 | tvars.exe 3 | -------------------------------------------------------------------------------- /demo_templates/golangtutorials/tvars/tvars.go: -------------------------------------------------------------------------------- 1 | /* 2 | From: 3 | http://golangtutorials.blogspot.com/2011/10/go-templates-part-2.html 4 | */ 5 | package main 6 | 7 | /* 8 | You can create local variables for the pipelines within the template by 9 | prefixing the variable name with a "$" sign. Variable names have to be composed 10 | of alphanumeric characters and the underscore. In the example below I have used 11 | a few variations that work for variable names. 12 | */ 13 | import ( 14 | "os" 15 | "text/template" 16 | ) 17 | 18 | func main() { 19 | t := template.Must(template.New("name").Parse("{{with $3 := `hello`}}{{$3}}{{end}}!\n")) 20 | t.Execute(os.Stdout, nil) 21 | 22 | t1 := template.Must(template.New("name1").Parse("{{with $x3 := `hola`}}{{$x3}}{{end}}!\n")) 23 | t1.Execute(os.Stdout, nil) 24 | 25 | t2 := template.Must(template.New("name2").Parse("{{with $x_1 := `hey`}}{{$x_1}} {{.}} {{$x_1}}{{end}}!\n")) 26 | t2.Execute(os.Stdout, nil) 27 | } 28 | -------------------------------------------------------------------------------- /demo_templates/golangtutorials/twithend/.gitignore: -------------------------------------------------------------------------------- 1 | twithend 2 | twithend.exe 3 | -------------------------------------------------------------------------------- /demo_templates/golangtutorials/twithend/twithend.go: -------------------------------------------------------------------------------- 1 | /* 2 | From: 3 | http://golangtutorials.blogspot.com/2011/10/go-templates-part-2.html 4 | */ 5 | package main 6 | 7 | import ( 8 | "os" 9 | "text/template" 10 | ) 11 | 12 | func main() { 13 | t, _ := template.New("test").Parse("{{with `hello`}}{{.}}{{end}}!\n") 14 | t.Execute(os.Stdout, nil) 15 | 16 | t1, _ := template.New("test").Parse("{{with `hello`}}{{.}} {{with `Mary`}}{{.}}{{end}}{{end}}!\n") //when nested, the dot takes the value according to closest scope. 17 | t1.Execute(os.Stdout, nil) 18 | } 19 | -------------------------------------------------------------------------------- /demo_templates/insdata/.gitignore: -------------------------------------------------------------------------------- 1 | insdata 2 | insdata.exe 3 | -------------------------------------------------------------------------------- /demo_templates/insdata/insdata.go: -------------------------------------------------------------------------------- 1 | /* 2 | From: https://astaxie.gitbooks.io/build-web-application-with-golang/en/07.4.html 3 | */ 4 | package main 5 | 6 | import ( 7 | "html/template" 8 | "os" 9 | ) 10 | 11 | type Person struct { 12 | UserName string 13 | } 14 | 15 | func main() { 16 | t := template.New("fieldname example") 17 | t, _ = t.Parse("hello {{.UserName}}!\n") 18 | p := Person{UserName: "Guy"} 19 | t.Execute(os.Stdout, p) 20 | } 21 | -------------------------------------------------------------------------------- /demo_templates/jst/.gitignore: -------------------------------------------------------------------------------- 1 | jst 2 | jst.exe 3 | -------------------------------------------------------------------------------- /demo_templates/jst/jst.go: -------------------------------------------------------------------------------- 1 | /* 2 | js function example. 3 | */ 4 | package main 5 | 6 | import ( 7 | "os" 8 | "text/template" 9 | ) 10 | 11 | type Person struct { 12 | UserName string 13 | UserID int 14 | } 15 | 16 | func main() { 17 | // Not sure I see a practical use for the 'js' function. 18 | t := template.New("JS example") 19 | as := `{{js .}} 20 | ` 21 | t, _ = t.Parse(as) 22 | p := Person{UserName: "Guy", UserID: 123456} 23 | // The output here is somewhat unexpected. At the very least, it is not 24 | // what I anticipated. 25 | t.Execute(os.Stdout, p) 26 | } 27 | -------------------------------------------------------------------------------- /demo_templates/must/.gitignore: -------------------------------------------------------------------------------- 1 | must 2 | must.exe 3 | -------------------------------------------------------------------------------- /demo_templates/must/must.go: -------------------------------------------------------------------------------- 1 | /* 2 | Example from: 3 | https://astaxie.gitbooks.io/build-web-application-with-golang/en/07.4.html 4 | */ 5 | 6 | package main 7 | 8 | import ( 9 | "fmt" 10 | "text/template" 11 | ) 12 | 13 | func main() { 14 | tOk := template.New("first") 15 | template.Must(tOk.Parse(" some static text /* and a comment */")) 16 | fmt.Println("The first one parsed OK.") 17 | 18 | template.Must(template.New("second").Parse("some static text {{ .Name }}")) 19 | fmt.Println("The second one parsed OK.") 20 | 21 | fmt.Println("The next one ought to fail.") 22 | tErr := template.New("check parse error with Must") 23 | template.Must(tErr.Parse(" some static text {{ .Name }")) 24 | } 25 | -------------------------------------------------------------------------------- /demo_templates/nestedfields/.gitignore: -------------------------------------------------------------------------------- 1 | nestedfields 2 | nestedfields.exe 3 | 4 | -------------------------------------------------------------------------------- /demo_templates/nestedfields/nestedfields.go: -------------------------------------------------------------------------------- 1 | /* 2 | Example from: 3 | https://astaxie.gitbooks.io/build-web-application-with-golang/en/07.4.html 4 | */ 5 | 6 | package main 7 | 8 | import ( 9 | "os" 10 | "text/template" 11 | ) 12 | 13 | type Friend struct { 14 | Fname string 15 | } 16 | 17 | type Person struct { 18 | UserName string 19 | Emails []string 20 | Friends []*Friend 21 | } 22 | 23 | func main() { 24 | f1 := Friend{Fname: "Chris"} 25 | f2 := Friend{Fname: "George"} 26 | t := template.New("fieldname example 2") 27 | t, _ = t.Parse(`hello {{.UserName}}! 28 | {{range .Emails}} 29 | an email {{.}} 30 | {{end}} 31 | {{/* Next section */}} 32 | {{with .Friends}} 33 | {{range .}} 34 | my friend's name is {{.Fname}} 35 | {{end}} 36 | {{end}} 37 | `) 38 | p := Person{UserName: "Guy", 39 | Emails: []string{"guy@gmallard.com", "allard.guy.m@gmail.com"}, 40 | Friends: []*Friend{&f1, &f2}} 41 | t.Execute(os.Stdout, p) 42 | } 43 | -------------------------------------------------------------------------------- /demo_templates/nestedtemplates/.gitignore: -------------------------------------------------------------------------------- 1 | nestedtemplates 2 | nestedtemplates.exe 3 | -------------------------------------------------------------------------------- /demo_templates/nestedtemplates/nestedtemplages.go: -------------------------------------------------------------------------------- 1 | /* 2 | Example (modified) from: 3 | https://astaxie.gitbooks.io/build-web-application-with-golang/en/07.4.html 4 | */ 5 | 6 | package main 7 | 8 | import ( 9 | "fmt" 10 | "io/ioutil" 11 | "os" 12 | "strings" 13 | "text/template" 14 | ) 15 | 16 | var templates *template.Template 17 | 18 | func main() { 19 | var allFiles []string 20 | files, err := ioutil.ReadDir("./tmplfiles") 21 | if err != nil { 22 | fmt.Println(err) 23 | } 24 | for _, file := range files { 25 | filename := file.Name() 26 | if strings.HasSuffix(filename, ".tmpl") { 27 | allFiles = append(allFiles, "./tmplfiles/"+filename) 28 | } 29 | } 30 | 31 | templates, err = template.ParseFiles(allFiles...) // parses all .tmpl files in the 'templates' folder 32 | 33 | //s1 := templates.Lookup("header.tmpl") 34 | //s1.ExecuteTemplate(os.Stdout, "header", nil) 35 | //fmt.Println() 36 | s2 := templates.Lookup("content.tmpl") 37 | s2.ExecuteTemplate(os.Stdout, "content", nil) 38 | fmt.Println() 39 | //s3 := templates.Lookup("footer.tmpl") 40 | //s3.ExecuteTemplate(os.Stdout, "footer", nil) 41 | //fmt.Println() 42 | //s3.Execute(os.Stdout, nil) 43 | } 44 | -------------------------------------------------------------------------------- /demo_templates/nestedtemplates/tmplfiles/content.tmpl: -------------------------------------------------------------------------------- 1 | {{define "content"}} 2 | {{template "header"}} 3 |