├── .gitignore
├── .markdownlint.json
├── docs
├── 404.html
├── command-line.html
├── control-structures.html
├── date-time.html
├── files.html
├── for-loops.html
├── functions.html
├── guess-game.html
├── hello.html
├── index.html
├── interfaces.html
├── json.html
├── maps.html
├── memcache.html
├── mysql.html
├── numbers.html
├── objects.html
├── read-dir.html
├── regexps.html
├── rest-api.html
├── slices.html
├── sorting.html
├── strings.html
├── structs.html
├── testing.html
└── web-server.html
├── pages
├── command-line.md
├── control-structures.md
├── date-time.md
├── files.md
├── for-loops.md
├── functions.md
├── guess-game.md
├── hello.md
├── index.md
├── interfaces.md
├── json.md
├── maps.md
├── memcache.md
├── mysql.md
├── numbers.md
├── objects.md
├── read-dir.md
├── regexps.md
├── rest-api.md
├── slices.md
├── sorting.md
├── strings.md
├── structs.md
├── testing.md
└── web-server.md
└── readme.md
/.gitignore:
--------------------------------------------------------------------------------
1 | docs/.htaccess
2 |
--------------------------------------------------------------------------------
/.markdownlint.json:
--------------------------------------------------------------------------------
1 | {
2 | "default": true,
3 | "MD003": { "style": "atx" },
4 | "MD007": { "indent": 4 },
5 | "MD013": { "line_length": 999 },
6 | "MD025": { "front_matter_title": false },
7 | "MD033": { "allowed_elements": [ "span", "figure", "figcaption", "video", "asciinema-player" ] },
8 | "no-hard-tabs": false,
9 | "whitespace": false
10 | }
11 |
--------------------------------------------------------------------------------
/docs/404.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Working with Go
9 |
10 |
11 |
12 | Page moved to https://mkaz.blog/working-with-go/
13 |
14 |
15 |
--------------------------------------------------------------------------------
/docs/command-line.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Working with Go
9 |
10 |
11 |
12 | Page moved to https://mkaz.blog/working-with-go/command-line/
13 |
14 |
15 |
--------------------------------------------------------------------------------
/docs/control-structures.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Working with Go
9 |
10 |
11 |
12 | Page moved to https://mkaz.blog/working-with-go/control-structures/
13 |
14 |
15 |
--------------------------------------------------------------------------------
/docs/date-time.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Working with Go
9 |
10 |
11 |
12 | Page moved to https://mkaz.blog/working-with-go/date-and-time/
13 |
14 |
15 |
--------------------------------------------------------------------------------
/docs/files.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Working with Go
9 |
10 |
11 |
12 | Page moved to https://mkaz.blog/working-with-go/files/
13 |
14 |
15 |
--------------------------------------------------------------------------------
/docs/for-loops.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Working with Go
9 |
10 |
11 |
12 | Page moved to https://mkaz.blog/working-with-go/loops/
13 |
14 |
15 |
--------------------------------------------------------------------------------
/docs/functions.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Working with Go
9 |
10 |
11 |
12 | Page moved to https://mkaz.blog/working-with-go/functions/
13 |
14 |
15 |
--------------------------------------------------------------------------------
/docs/guess-game.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Working with Go
9 |
10 |
11 |
12 | Page moved to https://mkaz.blog/working-with-go/guess-game/
13 |
14 |
15 |
--------------------------------------------------------------------------------
/docs/hello.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Working with Go
9 |
10 |
11 |
12 | Page moved to https://mkaz.blog/working-with-go/hello-world/
13 |
14 |
15 |
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Working with Go
9 |
10 |
11 |
12 | Page moved to https://mkaz.blog/working-with-go/
13 |
14 |
15 |
--------------------------------------------------------------------------------
/docs/interfaces.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Working with Go
9 |
10 |
11 |
12 | Page moved to https://mkaz.blog/working-with-go/interfaces/
13 |
14 |
15 |
--------------------------------------------------------------------------------
/docs/json.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Working with Go
9 |
10 |
11 |
12 | Page moved to https://mkaz.blog/working-with-go/json/
13 |
14 |
15 |
--------------------------------------------------------------------------------
/docs/maps.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Working with Go
9 |
10 |
11 |
12 | Page moved to https://mkaz.blog/working-with-go/maps/
13 |
14 |
15 |
--------------------------------------------------------------------------------
/docs/memcache.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Working with Go
9 |
10 |
11 |
12 | Page moved to https://mkaz.blog/working-with-go/memcache/
13 |
14 |
15 |
--------------------------------------------------------------------------------
/docs/mysql.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Working with Go
9 |
10 |
11 |
12 | Page moved to https://mkaz.blog/working-with-go/mysql/
13 |
14 |
15 |
--------------------------------------------------------------------------------
/docs/numbers.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Working with Go
9 |
10 |
11 |
12 | Page moved to https://mkaz.blog/working-with-go/numbers/
13 |
14 |
15 |
--------------------------------------------------------------------------------
/docs/objects.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Working with Go
9 |
10 |
11 |
12 | Page moved to https://mkaz.blog/working-with-go/objects/
13 |
14 |
15 |
--------------------------------------------------------------------------------
/docs/read-dir.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Working with Go
9 |
10 |
11 |
12 | Page moved to https://mkaz.blog/working-with-go/directories/
13 |
14 |
15 |
--------------------------------------------------------------------------------
/docs/regexps.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Working with Go
9 |
10 |
11 |
12 | Page moved to https://mkaz.blog/working-with-go/regexp/
13 |
14 |
15 |
--------------------------------------------------------------------------------
/docs/rest-api.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Working with Go
9 |
10 |
11 |
12 | Page moved to https://mkaz.blog/working-with-go/rest-api/
13 |
14 |
15 |
--------------------------------------------------------------------------------
/docs/slices.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Working with Go
9 |
10 |
11 |
12 | Page moved to https://mkaz.blog/working-with-go/arrays/
13 |
14 |
15 |
--------------------------------------------------------------------------------
/docs/sorting.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Working with Go
9 |
10 |
11 |
12 | Page moved to https://mkaz.blog/working-with-go/sorting/
13 |
14 |
15 |
--------------------------------------------------------------------------------
/docs/strings.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Working with Go
9 |
10 |
11 |
12 | Page moved to https://mkaz.blog/working-with-go/strings/
13 |
14 |
15 |
--------------------------------------------------------------------------------
/docs/structs.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Working with Go
9 |
10 |
11 |
12 | Page moved to https://mkaz.blog/working-with-go/structs/
13 |
14 |
15 |
--------------------------------------------------------------------------------
/docs/testing.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Working with Go
9 |
10 |
11 |
12 | Page moved to https://mkaz.blog/working-with-go/testing/
13 |
14 |
15 |
--------------------------------------------------------------------------------
/docs/web-server.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Working with Go
9 |
10 |
11 |
12 | Page moved to https://mkaz.blog/working-with-go/web-server/
13 |
14 |
15 |
--------------------------------------------------------------------------------
/pages/command-line.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Command-line
3 | layout: page
4 | order:13
5 | ---
6 |
7 | # Command-line Args
8 |
9 | ## os.Args
10 |
11 | Command-line args are stored as a slice in `os.Args`. The first argument in list is program itself.
12 |
13 | ```go
14 | num_args := len(os.Args)
15 | ```
16 |
17 | You can check to see if any command-line arguments were passed in
18 |
19 | ```go
20 | if num_args < 2 {
21 | fmt.Println(">> No args passed in")
22 | }
23 | ```
24 |
25 | ## Flag Library
26 |
27 | Use the [`flag`](https://golang.org/pkg/flag/) standard library to parse command-line arguments. The flag library parses parameters passed in and flags for invalid types, invalud flags, and handles most needs for creating a command-line program.
28 |
29 | ```go
30 | var s string
31 | flag.StringVar(&s, "str", "default value", "text description")
32 | ```
33 |
34 | Usage:
35 |
36 | ```shell
37 | $ ./program -str "Hello"
38 | ```
39 |
40 | ## Full Example
41 |
42 | Here is a full example program showing how to use command-line arguments and flags in Go
43 |
44 | ```go
45 | package main
46 |
47 | import (
48 | "flag"
49 | "fmt"
50 | "os"
51 | )
52 |
53 | // global vars
54 | var str string
55 | var num int
56 | var help bool
57 |
58 | func main() {
59 |
60 | // define flags
61 | flag.StringVar(&str, "str", "default value", "text description")
62 | flag.IntVar(&num, "num", 5, "text description")
63 | flag.BoolVar(&help, "help", false, "Display Help")
64 |
65 | // parse
66 | flag.Parse()
67 |
68 | // check if help was called explicitly
69 | if help {
70 | fmt.Println(">> Display help screen")
71 | os.Exit(1)
72 | }
73 |
74 | // See values assigned
75 | fmt.Println(">> String:", str)
76 | fmt.Println(">> Number:", num)
77 |
78 | // last command-line argument
79 | fmt.Println(">> Last Item:", os.Args[num_args-1])
80 |
81 | // the os.Args will include flags for example
82 | // go run command-line-args.go --str=Foo filename
83 | // os.Args[1] = "--str=Foo"
84 |
85 | // If you have flags and want just the arguments
86 | // then after calling flag.Parse() you can call
87 | // flag.Args which store only the args
88 | args := flag.Args()
89 | if len(args) > 0 {
90 | fmt.Println(">> Flag Arg:", args[0])
91 | }
92 |
93 | }
94 | ```
95 |
96 | Run with different parameters
97 |
98 | ```shell
99 | $ go run command-line.go
100 | >> No args passed in
101 | >> String: default value
102 | >> Number: 5
103 | >> Last Item: command-line.go
104 |
105 | $ go run command-line.go --str=Foo --num=8 filename
106 | >> String: Foo
107 | >> Number: 8
108 | >> Last Item: filename
109 | >> Flag Arg: filename
110 | ```
111 |
--------------------------------------------------------------------------------
/pages/control-structures.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Control Structures
3 | layout: page
4 | order: 5
5 | ---
6 |
7 | # Control Structures
8 |
9 | Using If, Else, Switch and Conditionals in Go.
10 |
11 |
12 | ## If, Else
13 |
14 | Go is not picky, conditionals don't require parentheses.
15 |
16 | ```go
17 | if num > 3 {
18 | fmt.Println("Many")
19 | }
20 | ```
21 |
22 | Go is picky, `else` must be on the same line as closing `if` bracket.
23 |
24 | ```go
25 | if num == 1 {
26 | fmt.Println("One")
27 | } else if num == 2 {
28 | fmt.Println("Two")
29 | } else {
30 | fmt.Println("Many")
31 | }
32 | ```
33 |
34 | ## Switch Statement
35 |
36 | Using switch and case conditionals in Go. Note: Go auto breaks each case, this avoids the typical issue of cascading when forgetting a break statement.
37 |
38 | ```go
39 | switch num {
40 | case 1:
41 | fmt.Println("One")
42 | case 2:
43 | fmt.Println("Two")
44 | default:
45 | fmt.Println("Many")
46 | }
47 | }
48 | ```
49 |
50 | An alternative switch syntax allows you to check beyond equality:
51 |
52 | ```go
53 | switch {
54 | case num == 1:
55 | fmt.Println("One")
56 | case num == 2:
57 | fmt.Println("Two")
58 | case num > 2:
59 | fmt.Println("Many")
60 | default:
61 | fmt.Println("Less than 1")
62 | }
63 | }
64 | ```
65 |
--------------------------------------------------------------------------------
/pages/date-time.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Date/Time
3 | layout: page
4 | order: 14
5 | ---
6 |
7 | # Working with Date and Time
8 |
9 | The [`time`](http://golang.org/pkg/time/) standard library provides the methods needed for working with dates and time in Go.
10 |
11 |
12 | ## Now
13 |
14 | Create a date using `time.Now()`, returns a `Time` type
15 |
16 | ```go
17 | now := time.Now()
18 | ```
19 |
20 | Create a Unix timestamp, returns a `int64` type
21 |
22 | ```go
23 | unix := time.Unix()
24 | ```
25 |
26 |
27 | ## Format Date
28 |
29 | Go uses a format-by-example method for formating dates. This is odd and you may never get used to it, I still haven't. There is a base date `Monday, January 2nd, 2006 at 15:04:05` and all formats specified are based off examples using that date.
30 |
31 | If you want a date in `YYYY-MM-DD` format, you would use `2006-01-02` as the format string.
32 |
33 | It is debatable what is easier to remember? The sample date or the `%b %c` formats other languages use. A way to try to remember is `Month=1, Day=2, Hour=3, Minute=4, Sec=5, Year=6`
34 |
35 | ```go
36 | fmt.Println(now.Format("Mon, Jan 2, 2006 at 3:04pm"))
37 | ```
38 |
39 | Use a method to get any part of the date, see [`Time`](http://golang.org/pkg/time/#Time) documentation for list of available time methods.
40 |
41 | ```go
42 | fmt.Println("Year: ", now.Year())
43 | fmt.Println("Month: ", now.Month())
44 | ```
45 |
46 | ## Built-in Formats
47 |
48 | The time library contains a set of [built-in constants](http://golang.org/pkg/time/#pkg-constants) to assist with standard date formatting.
49 |
50 | ```go
51 | const (
52 | ANSIC = "Mon Jan _2 15:04:05 2006"
53 | UnixDate = "Mon Jan _2 15:04:05 MST 2006"
54 | RubyDate = "Mon Jan 02 15:04:05 -0700 2006"
55 | RFC822 = "02 Jan 06 15:04 MST"
56 | RFC822Z = "02 Jan 06 15:04 -0700" // RFC822 with numeric zone
57 | RFC850 = "Monday, 02-Jan-06 15:04:05 MST"
58 | RFC1123 = "Mon, 02 Jan 2006 15:04:05 MST"
59 | RFC1123Z = "Mon, 02 Jan 2006 15:04:05 -0700" // RFC1123 with numeric zone
60 | RFC3339 = "2006-01-02T15:04:05Z07:00"
61 | RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"
62 | Kitchen = "3:04PM"
63 | // Handy time stamps.
64 | Stamp = "Jan _2 15:04:05"
65 | StampMilli = "Jan _2 15:04:05.000"
66 | StampMicro = "Jan _2 15:04:05.000000"
67 | StampNano = "Jan _2 15:04:05.000000000"
68 | )
69 | ```
70 |
71 | An example using the constant formats
72 |
73 | ```go
74 | fmt.Println(now.Format(time.RFC850))
75 | fmt.Println(now.Format(time.RFC1123))
76 | ```
77 |
78 | ## Setting a Specific Date
79 |
80 | A time zone is required when specifying a date, you can build a time zone using the LoadLocation, or you could also use the `time.UTC` constant for UTC.
81 |
82 | ```go
83 | est, _ := time.LoadLocation("EST")
84 | july4 := time.Date(1776, 7, 4, 12, 15, 0, 0, est)
85 | ```
86 |
87 | ## Parse Dates
88 |
89 | You can parse user inputted dates using known formats by specifying the format by example
90 |
91 | ```go
92 | input_format := "1/2/2006 3:04pm"
93 | user_str := "4/16/2014 11:38am"
94 | user_date, err := time.Parse(input_format, user_str)
95 | if err != nil {
96 | fmt.Println(">>> Error parsing date string")
97 | }
98 | fmt.Println("User Date: ", user_date.Format("Jan 2, 2006 @ 3:04pm"))
99 | ```
100 |
101 | ## Date/Time Comparisons
102 |
103 | You can use `Before()`, `After()`, or `Equal()` to compare dates.
104 |
105 | ```go
106 | if july4.Before(now) {
107 | fmt.Println("July 4 is before Now ")
108 | }
109 | ```
110 |
111 | ## Date Arithmetic
112 |
113 | The Time library also includes a [`Duration type`](https://golang.org/pkg/time/#Duration) which represents the different between two dates. The Duration type does not include days due to timezones and daylight savings.
114 |
115 | Calculate a `Duration:`
116 |
117 | ```go
118 | diff := now.Sub(july4)
119 | ```
120 |
121 | Use a `Duration`:
122 |
123 | ```go
124 | fmt.Printf("July 4 was about %d hours ago \n", diff.Hours())
125 | ```
126 |
127 | You can add dates using Durations
128 |
129 | ```go
130 | twodaysDiff := time.Hour * 24 * 2
131 | twodays := now.Add(twodaysDiff)
132 | fmt.Println("Two Days: ", twodays.Format(time.ANSIC))
133 | ```
134 |
--------------------------------------------------------------------------------
/pages/files.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Files
3 | layout: page
4 | order: 9
5 | ---
6 |
7 | # Working with Files
8 |
9 | ## Reading File
10 |
11 | You can read a complete file in using `ioutil.ReadFile`. See [ReadFile documentation](https://golang.org/pkg/io/ioutil/#ReadFile)
The function returns two variables, the first the content of the file. The second variable is the error if one occurred. If no error, than `err` will be `nil`
12 |
13 | ```go
14 | filename := "./extras/rabbits.txt"
15 |
16 | content, err := ioutil.ReadFile(filename)
17 | if err != nil {
18 | log.Fatalln("Error reading file", filename)
19 | }
20 | ```
21 |
22 | The content is returned as a `[]byte` and not a string. You need to cast to a string to use as such, for example to display. Use `string()` to cast a `[]byte` to `string` type.
23 |
24 | ```go
25 | fmt.Println(string(content))
26 | ```
27 |
28 | ## Check if File Exists
29 |
30 | One of the above errors can be if the file does not exist. You can use [`os.Stat`](https://golang.org/pkg/os/#Stat) to check explicitly if file exists without trying to open.
31 |
32 | ```go
33 | if _, err := os.Stat("junk.foo"); os.IsNotExist(err) {
34 | fmt.Println(">>>")
35 | fmt.Println("File: junk.foo does not exist")
36 | }
37 | ```
38 |
39 | ## Read File Line-by-Line
40 |
41 | One way to process a file line by line, would be to read the entire file in, like the first example above, and then split on the line ending.
42 |
43 | ```go
44 | lines = strings.split( string(content), "\n" )
45 | ```
46 |
47 | The above is perfectly fine and works for most files. If you have a large file, for example one that can not be stored in memory, you can use the `bufio` package. See [bufio package](https://golang.org/pkg/bufio) documentaiton.
48 |
49 | Here is a way to process a large file line-by-line in golang.
50 |
51 | ```go
52 | file, err := os.Open(filename)
53 | if err != nil {
54 | fmt.Println("Error opening file: ", err)
55 | }
56 | defer file.Close() // see explanation below
57 |
58 | // Use bufio scanner, the default Scan method is by line
59 | scanner := bufio.NewScanner(file)
60 | for scanner.Scan() {
61 | line := scanner.Text()
62 | fmt.Println(line)
63 | }
64 | ```
65 |
66 | The `defer` statement defers the execution until the surrounding function (or overall program) completes. You should always use `defer` for something that needs to be closed, or cleaned up.
67 |
68 | ## Write to a new File
69 |
70 | Use [`ioutil.WriteFile`](https://golang.org/pkg/io/ioutil/#WriteFile) to write a file out. The function takes three variables, the filename, the content (as a `[]byte`) and the file system mode.
71 |
72 | ```go
73 | outfile := "output.txt"
74 | err = ioutil.WriteFile(outfile, content, 0644)
75 | if err != nil {
76 | fmt.Println("Error writing file: ", err)
77 | } else {
78 | fmt.Println(">>>")
79 | fmt.Println("Created: ", outfile)
80 | }
81 | ```
82 |
83 | ## Append to an existing File
84 |
85 | You can write out to an existing file appending the content using the following.
86 |
87 | ```go
88 | af, err := os.OpenFile(outfile, os.O_APPEND|os.O_WRONLY, 0644)
89 | if err != nil {
90 | fmt.Println("Error appending to file:", err)
91 | }
92 | defer af.Close()
93 | if _, err = af.WriteString("Appending this text"); err != nil {
94 | fmt.Println("Error writing to file:", err)
95 | }
96 | ```
97 |
98 |
99 | ## Using Filepath
100 |
101 |
102 | Use the `filepath` package for working with cross-platform paths properly. See [filepath package](https://golang.org/pkg/path/filepath/) documentaiton.
For example, use `filepath.Join` for creating a path with directory.
103 |
104 | ```go
105 | package main
106 |
107 | import (
108 | "fmt"
109 | "path/filepath"
110 | )
111 |
112 | func main() {
113 | fmt.Println(filepath.Join("a", "b", "file.ext"))
114 | }
115 | ```
116 |
117 | See filepath package documentation for additional function, including splitting paths, checking filename extension, base and more.
118 |
--------------------------------------------------------------------------------
/pages/for-loops.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: For Loops
3 | layout: page
4 | order: 6
5 | ---
6 |
7 | # Loops
8 |
9 | Go uses `for` for all loops, there is no `while` or `do-while` loops.
10 |
11 | ## For Loop
12 |
13 | ```go
14 |
15 | alphas := []string{"abc", "def", "ghi"}
16 |
17 | // standard for loop
18 | for i := 0; i < len(alphas); i++ {
19 | fmt.Printf("%d: %s \n", i, alphas[i])
20 | }
21 |
22 | // counting backwards
23 | for i := len(alphas)-1; i >= 0; i-- {
24 | fmt.Printf("%d: %s \n", i, alphas[i])
25 | }
26 | ```
27 |
28 | ## Using Range
29 |
30 | Iterating over an array is easier using `range` function.
31 |
32 | ```go
33 | for i, val := range alphas {
34 | fmt.Printf("%d: %s \n", i, val)
35 | }
36 | ```
37 |
38 | If you did not care about the value and only wanted the index
39 |
40 | ```go
41 | for i := range alphas {
42 | fmt.Println(i)
43 | }
44 | ```
45 |
46 | If you did not care about the index and only the value, you need to use the `_` character.
47 |
48 | ```go
49 | for _, val := range alphas {
50 | fmt.Println(val)
51 | }
52 | ```
53 |
54 | ## Use For like While
55 |
56 | ```go
57 | x := 0
58 | for x < 10 {
59 | fmt.Println(x)
60 | x++
61 | }
62 | ```
63 |
64 | ## Infinite Loop
65 |
66 | ```go
67 | for {
68 | fmt.Print(".")
69 | }
70 | ```
71 |
72 |
--------------------------------------------------------------------------------
/pages/functions.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Functions
3 | layout: page
4 | order: 4
5 | ---
6 |
7 | # Functions
8 |
9 | Examples on how to use functions in Go.
10 |
11 | ## Basic Function
12 |
13 | An example of a basic function accepting one parameter and no return value. The parameter type must be specified in the function definition.
14 |
15 | ```go
16 | func Echo(s string) {
17 | fmt.Println(s)
18 | }
19 | ```
20 |
21 | ## Function with Return Value
22 |
23 | Defining a function with a return value, you must specify the type for the return value.
24 |
25 | ```go
26 | func Say(s string) string {
27 | phrase := "Hello " + s
28 | return phrase
29 | }
30 | ```
31 |
32 | ## Named Returned Value
33 |
34 | You can define a function with a named return variable. By using a named variable it initializes the variables. Also, by using a named variable you do not need to include the variable in return statement it will return the current value of the variable on return.
35 |
36 | ```go
37 | func Say(s string) (phrase string) {
38 | phrase = "Hello " + s
39 | return
40 | }
41 | ```
42 |
43 | ## Multiple Parameters
44 |
45 | Function with multiple parameters and return values
46 |
47 | ```go
48 | func Divide(x, y float64) (float64, float64) {
49 | q := math.Trunc(x / y)
50 | r := math.Mod(x, y)
51 | return q, r
52 | }
53 | ```
54 |
55 | Function with multiple parameters and named return values. If the types are the same you can specify the type once at the end
56 |
57 | ```go
58 | func Divide2(x, y float64) (q, r float64) {
59 | q = math.Trunc(x / y)
60 | r = math.Mod(x, y)
61 | return
62 | }
63 | ```
64 |
65 | ## Variadic Parameters
66 |
67 | A variadic function is a function that accepts an arbitrary number of arguments. Here is an example function accepting any number of ints. A slice is created out of the parameters passed in.
68 |
69 | ```go
70 | func Sum(x ...int) int {
71 | sum := 0
72 | for _, v := range x {
73 | sum += v
74 | }
75 | return sum
76 | }
77 | ```
78 |
79 | You can call the function with multiple parameters:
80 |
81 | ```go
82 | sum := Sum(1,3,5,7)
83 | fmt.Println(sum)
84 | ```
85 |
86 | You can also call using the spread operator:
87 |
88 | ```go
89 | nums := []int{1, 2, 3, 4, 5 }
90 | sum := Sum(nums...)
91 | fmt.Println(sum)
92 | ```
93 |
94 |
--------------------------------------------------------------------------------
/pages/guess-game.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Guessing Game
3 | layout: page
4 | order: 18
5 | ---
6 |
7 | # Guessing Game
8 |
9 | An example of the guessing game picking a number between 1-100.
10 |
11 |
12 | ## Random umber
13 |
14 | The [`math/rand`](https://golang.org/pkg/math/rand/) standard library is used to generate the random number.
15 |
16 | Note, you must seed the generator, for random this is easiest done using `time.Now().UnixNano()`. You can also seed the generator with a known value, such as a user id to get a deterministic random number.
17 |
18 | ```go
19 | rand.Seed(time.Now().UnixNano())
20 | fmt.Println(rand.Intn(100))
21 | ```
22 |
23 | ## Example Game
24 |
25 | Here is the example guessing game
26 |
27 | ```go
28 | package main
29 |
30 | import (
31 | "fmt"
32 | "math/rand"
33 | "time"
34 | )
35 |
36 | // automatically called on start
37 | func init() {
38 | // new random seed
39 | rand.Seed(time.Now().UnixNano())
40 | }
41 |
42 | func main() {
43 | // variable to store guess
44 | var guess int
45 |
46 | // variable to store number of guesses
47 | var count int
48 |
49 | // pick number to guess, add 1 since Intn gives [0,99]
50 | num := rand.Intn(100) + 1
51 |
52 | fmt.Println(">> I'm thinking of a number between 1-100 << ")
53 |
54 | // guessing loop
55 | for {
56 | // prompt user for guess
57 | fmt.Print("Guess: ")
58 | _, err := fmt.Scanf("%d", &guess)
59 | if err == nil {
60 | count += 1 // increment guess counter
61 | if guess > num {
62 | fmt.Println(" >> Too high ")
63 | } else if guess < num {
64 | fmt.Println(" >> Too low ")
65 | } else {
66 | fmt.Printf("Correct! It took you %d guesses!\n", count)
67 | break
68 | }
69 | } else { // an error with input
70 | fmt.Println(">> Please input a number")
71 | }
72 | }
73 | }
74 | ```
75 |
76 |
--------------------------------------------------------------------------------
/pages/hello.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Hola Mundo
3 | layout: page
4 | order: 1
5 | ---
6 |
7 | # Hola Mundo in Go
8 |
9 | Here is your first go program.
10 |
11 | ```go
12 | package main
13 |
14 | import "fmt"
15 |
16 | func main() {
17 | fmt.Println("Hola Mundo!")
18 | }
19 | ```
20 |
21 | All programs must be part of a package, you use `main` as the package for executable programs.
22 |
23 | You must import all packages used, including the standard library packages. In this example, the standard library [`fmt`](https://golang.org/pkg/fmt/) is used for formatted I/O.
24 |
25 | The standard library is your best friend in Go, it is extensive, often you will not need any third-party dependencies and can rely on just features in the standard library. You can browse all available standard library packages at: http://golang.org/pkg/.
26 |
27 | The main package requires a `main()` function, this is called when the program is run.
28 |
29 | Go will run `init()` function before `main()`, if it exists.
30 |
31 | Here is an expanded Hello World program that uses a global variable `phrase` defined as a string. All variables have types. The go compiler will automatically detect the type if possible.
32 |
33 | ```go
34 | package main
35 |
36 | import "fmt"
37 |
38 | var phrase string
39 |
40 | func init() {
41 | phrase = "Hola Mundo!"
42 | }
43 |
44 | func main() {
45 | fmt.Println(phrase)
46 | }
47 | ```
48 |
49 | To run the program in your terminal, save to a file `hello.go` and run using `go run`:
50 |
51 | ```shell
52 | $ go run hello.go
53 | Hola Mundo!
54 | ```
55 |
--------------------------------------------------------------------------------
/pages/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Working with Go
3 | layout: page
4 | unlisted: yes
5 | ---
6 |
7 | # Working with Go
8 |
9 | Working with Go is a set of examples in Go (golang) to get an experienced programmer familiar with Go. The Go language is often referred to as golang to help searches.
10 |
11 | Initially started as code and inline comments, but I found it more difficult to read and reference so migrated the content to this online tutorial.
12 |
13 | ## Install Go
14 |
15 | Go is distributed as a binary on the major platforms, Linux, FreeBSD, Mac OS X and Windows. It is available for both 32-bit and 64-bit architectures. See the official Getting Started with Go page for downloads and more instructions.
16 |
17 | Go is available in most Linux package environments:
18 |
19 | Ubuntu install: `apt-get install golang`
20 |
21 | Arch/Manjaro install: `pacman -S go`
22 |
23 |
24 | ## Running Go
25 |
26 | Go is a compiled language, you first need to compile program and then run the compiled binary. Go creates a single binary file that includes all necessary dependencies. This is convenient, once a binary is built you can copy and run to any similar system.
27 |
28 | Once you have Go installed, you can build a program:
29 |
30 | ```shell
31 | $ go build hello.go
32 | ```
33 |
34 | This will create the binary `hello`, you can then run:
35 |
36 | ```shell
37 | $ ./hello
38 | >> Hola Mundo!
39 | ```
40 |
41 | These lessons use `$` as the command prompt, and `>>` as the output from the program.
42 |
43 | Go includes a convenience function `run` that allows you to build and run in a single command. Note: this does not produce a binary.
44 |
45 | ```shell
46 | $ go run hello.go
47 | >> Hola Mundo!
48 | ```
49 |
50 | ## Development Environment
51 |
52 | Go is purposely light-weight and simple, making it quite flexible for just about any set of developer tools. A full blown IDE, such as Eclipse, is rarely used. Most developers opt for their favorite text editor and the terminal to run. This is how I develop on Linux.
53 |
54 |
55 |
56 | My primary editor is **Vim**. I recommend using the vim-go package which includes syntax support, and some convenience functions.
57 |
58 |
59 |
60 | Go has two tools that can automatically format your source code to the Go coding standard, `gofmt` comes with the standard install and `goimports` which will format and auto adjust import statements as needed.
61 |
62 |
63 |
64 | I highly recommend `goimports` because Go will not compile if imports are missing or extra. The `goimports` command saves this hassle when adding removing things during development.
65 |
66 | Whatever editor you use, I recommend installing and configuring goimports to automatically run on save.
67 |
68 | Install goimports:
69 |
70 | ```shell
71 | $ go get golang.org/x/tools/cmd/goimports
72 | ```
73 |
74 | For vim, you can setup to auto run `goimports` on save using vim-go:
75 |
76 | ```vim
77 | let g:go_fmt_command = "goimports"
78 | ```
79 |
80 | ## Contribute
81 |
82 | Working with Go source files are hosted at https://github.com/mkaz/working-with-go
83 |
84 |
85 | Additions, corrections and any contributions are encouraged, please submit a pull request with your change or an issue for a bug or fix. Thanks to all the contributors!
86 |
87 |
88 | ## Resources
89 |
90 | This set of examples assumes a certain level of programming experience and is intended for someone learning the Go language and not someone new to programming altogether.
91 |
92 | If you are starting out and want to learn how to program and choose Go as your first language, check out Learn Programming in Go
93 |
94 | The official Go language site has a Tour of Go that is an interactive walk through, another good introduction to the language.
95 |
--------------------------------------------------------------------------------
/pages/interfaces.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Interfaces
3 | layout: page
4 | order: 24
5 | ---
6 |
7 | # Interfaces
8 |
9 | An interface in Go is a type that defines a set of methods. Interfaces are the core of Go's type system. A type is said to satisfy an interface if it implements all the methods defined in that interface.
10 |
11 |
12 | ## Empty Interface
13 |
14 | The simplest example is the empty `interface{}`. This empty interface defines no methods thus all types implement it. This is often used to define a function that accepts any type, for example `fmt.Print` accepts any type and defined using
15 |
16 | ```go
17 | func Print(a ...interface{}) (n int, err error) {
18 | return Fprint(os.Stdout, a...)
19 | }
20 | ```
21 |
22 | The `...` is the spread operator, it allows for any number of `interface{}` types as arguments to the function.
23 |
24 |
25 | ## Interface with Methods
26 |
27 | Here is an example interface defining a single method. This defines a `Vehicle` interface as one that has the method `Alert()`
28 |
29 | ```go
30 | type Vehicle interface {
31 | Alert() string
32 | }
33 | ```
34 |
35 | Any type that implements the `Alert()` method is said to satisfy the `Vehicle` interface.
36 |
37 | When defining a struct you do not explicitly specify the interface it implements. Go determines automatically if a given type satisfies an interface if it defines all the methods.
38 |
39 | ```go
40 | type Car struct { }
41 |
42 | func (c Car) Alert() string {
43 | return "Honk! Honk!"
44 | }
45 | ```
46 |
47 | Defining another type:
48 |
49 | ```go
50 | type Bicycle struct { }
51 |
52 | func (b Bicycle) Alert() string {
53 | return "Ring! Ring!"
54 | }
55 | ```
56 |
57 | With the above definitions, you can create an array of Vehicles like so:
58 |
59 | ```go
60 | package main
61 |
62 | import "fmt"
63 |
64 | type Vehicle interface {
65 | Alert() string
66 | }
67 |
68 | type Car struct { }
69 |
70 | func (c Car) Alert() string {
71 | return "Honk! Honk!"
72 | }
73 |
74 | type Bicycle struct { }
75 |
76 | func (b Bicycle) Alert() string {
77 | return "Ring! Ring!"
78 | }
79 |
80 | func main() {
81 | c := Car{}
82 | b := Bicycle{}
83 |
84 | vehicles := []Vehicle{c, b}
85 | for _, v := range vehicles {
86 | fmt.Println(v.Alert())
87 | }
88 | }
89 | ```
90 |
--------------------------------------------------------------------------------
/pages/json.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: JSON
3 | layout: page
4 | order: 16
5 | ---
6 |
7 | # Working with JSON
8 |
9 | Use the [`encoding/json`](http://golang.org/pkg/encoding/json/) standard library for encoding to and decoding from JSON.
10 |
11 |
12 | ## Encoding to JSON
13 |
14 | Encoding a Go struct to JSON format uses the [`json.Marshal`](https://golang.org/pkg/encoding/json/#Marshal) method, this returns a `[]byte` of the struct.
15 |
16 | ```go
17 | // Create a struct to match the format of JSON
18 | type Person struct {
19 | Name string
20 | City string
21 | }
22 |
23 | p := Person{ Name: "Marcus", City: "San Francisco" }
24 |
25 | json, err := json.Marshal(p)
26 | if err != nil {
27 | fmt.Println("JSON Encoding Error", err)
28 | }
29 |
30 | fmt.Println(string(json))
31 | ```
32 |
33 | ## Decode from JSON
34 |
35 | To decode a JSON string to a Go struct, use the [`json.Unmarshal`](https://golang.org/pkg/encoding/json/#Unmarshal) method. Unmarshal accepts the `[]byte` of the JSON string to decode, and a pointer to the struct that matches the data structure.
36 |
37 | ```go
38 | json_str := `{ "Name": "Marcus", "City": "San Jose"}`
39 | var p Person
40 |
41 | if err := json.Unmarshal([]byte(json_str), &p); err != nil {
42 | fmt.Println("Error parsing JSON: ", err)
43 | }
44 |
45 | // output result
46 | fmt.Printf("Name: %v, City: %v\n", person.Name, person.City)
47 | ```
48 |
49 | ### Partial Data
50 |
51 | If a variable is already defined with values, the Unmarshaling will "fill in" the variable with the additional values from JSON.
52 |
53 | ### Read JSON from a File
54 |
55 | Since `Unmarshal` expects a `[]byte` to be read, reading from a file is straight-forward.
56 |
57 | ```go
58 | var people []Person
59 |
60 | file, err := ioutil.ReadFile("names.json")
61 | if err != nil {
62 | fmt.Println("Error reading file")
63 | }
64 |
65 | // the names.json file has an array of person objects, so read into people
66 | if err := json.Unmarshal(file, &people); err != nil {
67 | fmt.Println("Error parsing JSON", err)
68 | }
69 |
70 | // output result
71 | fmt.Println(people)
72 | ```
73 |
74 | ## Mapping Struct and JSON Field
75 |
76 | The JSON field names may not always match the struct names. Go will automatically manage uppercase and lowercase fields, but if they are completely different you can use struct field tags to label.
77 |
78 | ```go
79 | type Person {
80 | Name string `json:"username"`
81 | City string `json:"municipality"`
82 | }
83 | ```
84 |
85 | By defining the struct with the field tags, the Marshal and Unmarshaling will take the Go struct and write them to those JSON fields.
86 |
87 | ```go
88 | p := Person{ Name: "Marcus", City: "San Francisco" }
89 | json, _ := json.Marshal(p)
90 | fmt.Println(string(json))
91 |
92 | >> { "username": "Marcus", "municipality": "San Francisco" }
93 | ```
94 |
95 | ### Ignore Field
96 |
97 | You can ignore a field from being encoded or decoded to JSON, using `-` definition.
98 |
99 | ```go
100 | type Person {
101 | Name string
102 | City string
103 | Phone string `json:"-"`
104 | }
105 | ```
106 |
107 | The `Phone` field will be omitted from JSON operations.
108 |
109 | ### Omit Empty Fields
110 |
111 | Set a field to be ignored when empty, use `omitempty` so JSON encoding will not include the field.
112 |
113 | ```go
114 | type Person {
115 | Name string
116 | City string
117 | Phone string `json:",omitempty"`
118 | }
119 | ```
120 |
121 |
--------------------------------------------------------------------------------
/pages/maps.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Maps
3 | layout: page
4 | order: 8
5 | ---
6 |
7 | # Working with Maps
8 |
9 | A map is an associative array data type. You can define a map that uses any data type for the key or value.
10 |
11 | ## Make a Map
12 |
13 | Map uses the built-in `make` function to initialize, this creates an empty map with no keys.
14 |
15 | ```go
16 | m := make(map[string]string)
17 | m["c"] = "Cyan"
18 | m["y"] = "Yellow"
19 | m["m"] = "Magenta"
20 | m["k"] = "Black"
21 | ```
22 |
23 | You can also create the values on initialization using.
24 |
25 | ```go
26 | var m = map[string]string{
27 | "c": "Cyan",
28 | "y": "Yellow",
29 | "m": "Magenta",
30 | "k": "Black",
31 | }
32 | ```
33 |
34 | ## Iterate over a Map
35 |
36 | Use the same `range` function for iterating over a map, it returns the `key, value` pair.
37 |
38 | ```go
39 | for k, v := range m {
40 | fmt.Printf("Key: %s, Value: %s", k, v)
41 | }
42 | ```
43 |
44 | ## Retrieve a Map Item
45 |
46 | Get a single map item using brackets
47 |
48 | ```go
49 | c = m["c"]
50 | ```
51 |
52 |
53 | ## Delete a Map Item
54 |
55 | Use the `delete` built-in function, passing map and key.
56 |
57 | ```go
58 | delete(m, "c")
59 | ```
60 |
61 | ## Test Item Exists
62 |
63 | Test if a map contains an item, by checking the second value returned when fetching an item. If the item does not exists, it will be false.
64 |
65 | If the item does not exist the value returned will be the zero value, however the item may exist as the zero value in the map, so it is best practice to check the second value returned.
66 |
67 | ```go
68 | c, ok = m["p"]
69 | ```
70 |
71 |
72 |
--------------------------------------------------------------------------------
/pages/memcache.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Memcache
3 | layout: page
4 | order: 22
5 | ---
6 |
7 | # Storing Objects in Memcache
8 |
9 | How to store objects in memcache using [bradfitz/gomemcache](https://github.com/bradfitz/gomemcache) package. Memcache stores data as `[]byte`, so you need to first encode the object prior to storing.
10 |
11 | I typically encode using JSON, often the data is already or will soon be in JSON format, plus human readable helps debugging. If space and performance is a concern, see [`encoding/gob`](https://golang.org/pkg/encoding/gob/) for another format.
12 |
13 | ```go
14 | package main
15 |
16 | import (
17 | "encoding/json"
18 | "fmt"
19 |
20 | "github.com/bradfitz/gomemcache/memcache"
21 | )
22 |
23 | // define Dog object type
24 | type Dog struct {
25 | Name string
26 | Color string
27 | }
28 |
29 | func main() {
30 |
31 | // connect to memcache server
32 | mc := memcache.New("127.0.0.1:11211")
33 |
34 | // try to pull from memcache
35 | fetchItem, err := mc.Get("dog")
36 |
37 | // check for cache hit
38 | if err != memcache.ErrCacheMiss {
39 | if err != nil {
40 | fmt.Println("Error fetching from memcache", err)
41 | } else {
42 | fmt.Println("Cache hit!")
43 |
44 | dog, err := DecodeData(fetchItem.Value)
45 | if err != nil {
46 | fmt.Println("Error decoding data from memcache", err)
47 | } else {
48 | fmt.Println("Dog name is: ", dog.Name)
49 | }
50 | }
51 | }
52 |
53 | // create instance of object and set properties
54 | spot := Dog{Name: "Spot", Color: "brown"}
55 |
56 | // create memcache item to store
57 | setItem := memcache.Item{
58 | Key: "dog",
59 | Value: EncodeData(spot),
60 | Expiration: 300
61 | }
62 |
63 | err = mc.Set(&setItem)
64 | if err != nil {
65 | fmt.Println("Error setting memcache item", err)
66 | }
67 |
68 | // run twice
69 | }
70 |
71 | func DecodeData(raw []byte) (dog Dog, err error) {
72 | err = json.Unmarshal(raw, &dog)
73 | return dog, err
74 | }
75 |
76 | func EncodeData(dog Dog) []byte {
77 | enc, err := json.Marshal(dog)
78 | if err != nil {
79 | fmt.Println("Error encoding Action to JSON", err)
80 | }
81 | return enc
82 | }
83 | ```
84 |
--------------------------------------------------------------------------------
/pages/mysql.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: MySQL
3 | layout: page
4 | order: 23
5 | ---
6 |
7 | # Working with MySQL Database
8 |
9 |
10 | This is an example file for working with databases. Go provides an abstract datalayer using the [`database/sql`](https://golang.org/pkg/database/sql/) standard library. You need to load the specific driver your database first, than working with it is relatively the same.
11 |
12 | This example uses the [`go-sql-driver/mysql`](https://github.com/go-sql-driver/mysql).
13 |
14 | ## Example Tables
15 |
16 | You can create example table and data with the sql query below
17 |
18 | ```sql
19 | DROP TABLE IF EXISTS `posts`;
20 |
21 | CREATE TABLE `posts` (
22 | `id` int(6) unsigned NOT NULL AUTO_INCREMENT,
23 | `title` varchar(30) NOT NULL,
24 | `body` text NOT NULL,
25 | PRIMARY KEY (`id`)
26 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
27 |
28 | INSERT INTO `posts` (`id`, `title`, `body`)
29 | VALUES
30 | (1,'Hello World','The content of the hello world'),
31 | (2,'Hello Second World','The content of the hello second world');
32 |
33 | ```
34 |
35 | ## Example Program
36 |
37 | ```go
38 | // standard main package
39 | package main
40 |
41 | // Necessary packages to work with mysql databases
42 | import (
43 | "database/sql"
44 | "fmt"
45 |
46 | _ "github.com/go-sql-driver/mysql"
47 | )
48 |
49 | // dbConn connects to the database
50 | func dbConn() (db *sql.DB) {
51 |
52 | dbDriver := "mysql"
53 | dbUser := "root"
54 | dbPass := "root"
55 | dbName := "godb"
56 | db, err := sql.Open(dbDriver, dbUser+":"+dbPass+"@/"+dbName)
57 | if err != nil {
58 | panic(err.Error())
59 | }
60 | return db
61 | }
62 |
63 | // Post is the key to connect database to the program
64 | type Post struct {
65 | Id int
66 | Title string
67 | Body string
68 | }
69 |
70 | // getAll gets all the records from database
71 | func getAll() {
72 |
73 | db := dbConn()
74 |
75 | selDB, err := db.Query("SELECT * FROM Posts ORDER BY id DESC")
76 | if err != nil {
77 | panic(err.Error())
78 | }
79 |
80 | post := Post{}
81 | posts := []Post{}
82 |
83 | for selDB.Next() {
84 |
85 | var id int
86 | var title, body string
87 |
88 | err = selDB.Scan(&id, &title, &body)
89 | if err != nil {
90 | panic(err.Error())
91 | }
92 |
93 | post.Id = id
94 | post.Title = title
95 | post.Body = body
96 |
97 | posts = append(posts, post)
98 | }
99 |
100 | for _, post := range posts {
101 | fmt.Println(post.Title)
102 | }
103 |
104 | defer db.Close()
105 | }
106 |
107 | // getOne gets only one record from database
108 | func getOne(postId int) {
109 |
110 | db := dbConn()
111 |
112 | selDB, err := db.Query("SELECT * FROM Posts WHERE id=?", postId)
113 | if err != nil {
114 | panic(err.Error())
115 | }
116 |
117 | post := Post{}
118 |
119 | for selDB.Next() {
120 |
121 | var id int
122 | var title, body string
123 |
124 | err = selDB.Scan(&id, &title, &body)
125 | if err != nil {
126 | panic(err.Error())
127 | }
128 |
129 | post.Id = id
130 | post.Title = title
131 | post.Body = body
132 |
133 | }
134 |
135 | fmt.Println("Post Title : " + post.Title)
136 | fmt.Println("Post Body : " + post.Body)
137 |
138 | defer db.Close()
139 | }
140 |
141 | // add helps you to add new record to database
142 | func add() {
143 |
144 | db := dbConn()
145 |
146 | title := "Hello Second World"
147 | body := "The content of the hello second world"
148 | insertQuery, err := db.Prepare("INSERT INTO Posts(title, body) VALUES(?,?)")
149 | if err != nil {
150 | panic(err.Error())
151 | }
152 |
153 | insertQuery.Exec(title, body)
154 |
155 | fmt.Println("ADDED: Title: " + title + " | Body: " + body)
156 |
157 | defer db.Close()
158 |
159 | }
160 |
161 | // update helps you to update an existing record in the database
162 | func update(postId int) {
163 |
164 | db := dbConn()
165 |
166 | title := "Hello 1 World"
167 | body := "The content of the hello 1 world"
168 | updateQuery, err := db.Prepare("UPDATE Posts SET title=?, body=? WHERE id=?")
169 | if err != nil {
170 | panic(err.Error())
171 | }
172 |
173 | updateQuery.Exec(title, body, postId)
174 |
175 | fmt.Println("UPDATED: Title: " + title + " | Body: " + body)
176 |
177 | defer db.Close()
178 |
179 | }
180 |
181 | // delete helps you to delete an existing record in the database
182 | func delete(postId int) {
183 |
184 | db := dbConn()
185 |
186 | deleteQuery, err := db.Prepare("DELETE FROM Posts WHERE id=?")
187 | if err != nil {
188 | panic(err.Error())
189 | }
190 |
191 | deleteQuery.Exec(postId)
192 |
193 | fmt.Println("DELETED")
194 |
195 | defer db.Close()
196 |
197 | }
198 |
199 | func main() {
200 |
201 | //add()
202 | //update(1)
203 | //delete(1)
204 | //getOne(1)
205 | getAll()
206 |
207 | }
208 | ```
209 |
210 |
--------------------------------------------------------------------------------
/pages/numbers.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Numbers
3 | layout: page
4 | order: 2
5 | ---
6 |
7 | # Working with Numbers
8 |
9 | Go is a typed language, that means each variable is given a single specific number type. The common number types in golang are int, float, int64, float64. You need to be aware that each are differnet and function definitions and usage define the precise type expected.
10 |
11 | ## Convert String to Integer
12 |
13 | The most common conversion is a `string` to an `int`, for this you use the `strconv` package. See [strconv package](https://golang.org/pkg/strconv) documentation.
The strconv package contains various functions for converting strings to default types.
14 |
15 | Here is how to convert a string to an integer in golang:
16 |
17 | ```go
18 | str := 42
19 | ans, err := strconv.Atoi(str)
20 | if err != nil {
21 | fmt.Println("Error convert string to integer", err)
22 | }
23 | ```
24 |
25 | ## Convert Integer to a String
26 |
27 | Converting an integer to a string is a bit easier because there is no chance of an error. So it is just the single function `strconv.Itoa()`
28 |
29 | ```go
30 | str := strconv.Itoa(42)
31 | ```
32 |
33 | ## Convert Integer to a Float
34 |
35 | The `math` package has numerous helpful functions. See [math package](https://golang.org/pkg/math/) documentation
However, almost of the function require using a float64, so conversions are needed.
36 |
37 | If you are specifying a number, you can force a float type by using a decimal.
38 | ```go
39 | i := 42 // int type
40 | y := 42.0 // float type
41 | ```
42 |
43 | If an integer a variable, you can cast it to a float using
44 | ```go
45 | i := 42
46 | x := float64(i)
47 | ```
48 |
49 | ## Convert a String to a Float
50 |
51 | To convert a string to a float, use the `strconv.ParseFloat` function, the second argument is the bitSize, 64 is probably the most common to convert to a float64 type.
52 |
53 | ```go
54 | pi := "3.14159"
55 | x, err := strconv.ParseFloat(pi, 64)
56 | if err != nil {
57 | fmt.Println("Error convert string to float", err)
58 | }
59 | ```
60 |
61 | Note: You can print the type of a variable using `%T` in `fmt.Printf()`
62 |
63 | Example printing the type of a variable in golang:
64 | ```go
65 | fmt.Printf("Variable x has type %T and value %v", x, x )
66 | ```
67 |
--------------------------------------------------------------------------------
/pages/objects.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Objects
3 | layout: page
4 | order: 11
5 | ---
6 |
7 | # Object Oriented Programming
8 |
9 | Go does not have objects and classes, so is not a true object oriented programming. However, you can add methods to types. This gives you most of the same ability without the added complexity of full OOP.
10 |
11 | A method is a function with a _receiver_ defined first. Using the `Dog` type from the [structs example](/structs.html).
12 |
13 | ```go
14 | package main
15 |
16 | import "fmt"
17 |
18 | type Dog struct {
19 | Name string
20 | Color string
21 | }
22 |
23 | func (d Dog) Call() {
24 | fmt.Printf("Here comes a %s dog, %s.\n", d.Color, d.Name)
25 | }
26 |
27 | func main() {
28 |
29 | // create instance of dog
30 | Spot := Dog{Name: "Spot", Color: "brown"}
31 |
32 | // call object method
33 | Spot.Call()
34 | }
35 | ```
36 |
37 |
38 | ## Limitations
39 |
40 | You can define methods on custom types, but are limited to types that are defined in the same package as the method. So you cannot define a method on built-in types, you would first need to extend.
41 |
42 | ```go
43 | package main
44 |
45 | import "fmt"
46 |
47 | type MyInt int
48 |
49 | func (i MyInt) Double() MyInt {
50 | return i * 2
51 | }
52 |
53 | func main() {
54 | x := MyInt(3)
55 | fmt.Println(x.Double())
56 | }
57 | ```
58 |
59 |
--------------------------------------------------------------------------------
/pages/read-dir.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Directories
3 | layout: page
4 | order: 10
5 | ---
6 |
7 | # Directories
8 |
9 | ## Read Directory Recursively
10 |
11 | Use the [`filepath.Walk`](https://golang.org/pkg/path/filepath/#Walk) function to recursively walk down a directory.
12 |
13 | The `Walk` function accepts a path, and [`WalkFunc`](https://golang.org/pkg/path/filepath/#WalkFunc) as its parameters.
14 |
15 | The `WalkFunc` signature is `func(path string, info os.FileInfo, err error) error`, below is an example using an anonymous function with that signature.
16 |
17 | In the `WalkFunc` if you want to skip an entire directory, return `filepath.SkipDir` which is a special error variable defined in the library.
18 |
19 | ```go
20 | package main
21 |
22 | import (
23 | "fmt"
24 | "os"
25 | "path/filepath"
26 | )
27 |
28 | func main() {
29 | path := "./dir"
30 |
31 | filepath.Walk(path, func(fn string, fi os.FileInfo, err error) error {
32 | if err != nil {
33 | fmt.Println("Walker Error: ", err)
34 | return err
35 | }
36 |
37 | if fi.IsDir() {
38 | fmt.Println("Directory: ", fn)
39 | if fi.Name() == "skipme" {
40 | return filepath.SkipDir
41 | }
42 | } else {
43 | fmt.Println("File: ", fn)
44 | }
45 | return nil
46 | })
47 | }
48 | ```
49 |
50 | ## Create Directory if not exists
51 |
52 | Check if directory exists, create directory if it does not.
53 |
54 | ```go
55 | pathdir := filepath.Join(path, dir)
56 | if _, err := os.Stat(pathdir); os.IsNotExist(err) {
57 | mdErr := os.Mkdir(dirpath, 0755)
58 | if mdErr != nil {
59 | fmt.Println("Error making directory", mdErr)
60 | }
61 | }
62 | ```
63 |
64 | ## Get User Home Directory
65 |
66 | A platform independent way to get the user's home directory.
67 |
68 | ```go
69 | import "os/user"
70 |
71 | usr, err := user.Current()
72 | fmt.Println("User Home Directory:", usr.HomeDir)
73 | ```
74 |
75 |
--------------------------------------------------------------------------------
/pages/regexps.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Regexp
3 | layout: page
4 | order: 21
5 | ---
6 |
7 | # Regular Expressions
8 |
9 | Use the [`regexp`](http://golang.org/pkg/regexp/) standard library to work with regular expressions.
10 |
11 |
12 | ## Basic Regexp
13 |
14 | Create regular expression pattern to match 1 or more numbers
15 |
16 | ```go
17 | pattern := "[0-9]+"
18 |
19 | re, err := regexp.Compile(pattern)
20 | if err != nil {
21 | fmt.Println("Error compiling regex", err)
22 | }
23 | ```
24 |
25 | ### Test if Pattern Matches
26 |
27 | Use `MatchString` to test if pattern matches
28 |
29 | ```go
30 | str := "The 12 monkeys ate 48 bananas"
31 | if re.MatchString(str) {
32 | fmt.Println("Yes, matched a number")
33 | } else {
34 | fmt.Println("No, no match")
35 | }
36 | ```
37 |
38 | ### Return Match
39 |
40 | Use `FindString` to return match
41 |
42 | ```go
43 | result := re.FindString(str)
44 | fmt.Println("Number matched:", result)
45 | ```
46 |
47 | ### Return Multiple Matches
48 |
49 | Use `FindAllString` to return multiple matches, specify `-1` to return all.
50 |
51 | ```go
52 | results := re.FindAllString(str, 2)
53 | for i, v := range results {
54 | fmt.Printf("Match %d: %s\n", i, v)
55 | }
56 | ```
57 |
58 | ### Replace Match
59 |
60 | Use `ReplaceAllString` to replace matches
61 |
62 | ```go
63 | results := re.ReplaceAllString(str, "xx")
64 | fmt.Println("Result:", results)
65 | ```
66 |
67 | ## Case Insensitive
68 |
69 | The format for Go regular expression flags is different than typical. In Golang, the flag precedes the pattern, the syntax is, let's just say, not great. Here is an example using the case insensitive flag `i`
70 |
71 | ```go
72 | ptn := `(?i)^t.`
73 | str := "To be or not to be"
74 |
75 | re, err := regexp.Compile(ptn)
76 | if err != nil {
77 | fmt.Println("Error compiling regex", err)
78 | }
79 |
80 | // match string
81 | result := re.FindString(str)
82 | fmt.Println(result)
83 | ```
84 |
85 | ## Submatches
86 |
87 | Submatches are what Go calls the matches that are grabbed by `(.*)` inside of a regular expression.
88 |
89 | ```go
90 | str1 := "Hello @world@ Match"
91 | sub_re, _ := regexp.Compile("@(.*)@")
92 |
93 | m := sub_re.FindStringSubmatch(str1)
94 | // FindStringSubmatch returns [@world@ world]
95 | // so to just get the submatch you would use
96 | if len(m) > 1 {
97 | fmt.Println(m[1]) // submatch
98 | }
99 | ```
100 |
101 | ### Escaping Special Characters
102 |
103 | If you wanted to match brackets or other special characters and try to just escape them like so `\[(.*)\]` you will get an error for unknown escape sequence `[`
104 |
105 | You need to double up the slashes or a nicer solution is to use string literals and wrap in ticks instead of quotes
106 |
107 | ```go
108 | str2 := "A [word] here and [there]"
109 | esc_pattern := `\[(.*?)\]`
110 | esc_re, _ := regexp.Compile(esc_pattern)
111 |
112 | // this will only find the first
113 | fmt.Println(esc_re.FindStringSubmatch(str2))
114 |
115 | // use FindAll with second parameter for # of matches -1 = all
116 | fmt.Println(esc_re.FindAllStringSubmatch(str2, -1))
117 | ```
118 |
119 |
--------------------------------------------------------------------------------
/pages/rest-api.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: REST API
3 | layout: page
4 | order: 20
5 | ---
6 |
7 | # REST API
8 |
9 | Use the [`net/http`](https://golang.org/pkg/net/http/) standard library to create external http calls. You can combine this with the [parsing of JSON](json.html) to work with external APIs.
10 |
11 | The following example pulls in data from the Reddit API to get latest posts from golang sub. The key to understanding JSON decoding is understanding the data structure you receive the data. Once data structs are mapped, it becomes relatively straight forward
12 |
13 | ```go
14 | package main
15 |
16 | import (
17 | "encoding/json"
18 | "io/ioutil"
19 | "log"
20 | "net/http"
21 | )
22 |
23 | // create data structures to hold JSON data
24 | // this needs to match the fields in the JSON feed
25 | // see sample data fetch at bottom of this file
26 |
27 | // create an individual entry data structure
28 | // this does not need to hold every field, just the ones we want
29 | type Entry struct {
30 | Title string
31 | Author string
32 | URL string
33 | Permalink string
34 | }
35 |
36 | // the feed is the full JSON data structure
37 | // this sets up the array of Entry types (defined above)
38 | type Feed struct {
39 | Data struct {
40 | Children []struct {
41 | Data Entry
42 | }
43 | }
44 | }
45 |
46 | func main() {
47 | // url of REST endpoint we are grabbing data from
48 | url := "https://www.reddit.com/r/golang/new.json"
49 |
50 | // fetch url
51 | resp, err := http.Get(url)
52 | if err != nil {
53 | log.Fatalln("Error fetching:", err)
54 | }
55 | // defer response close
56 | defer resp.Body.Close()
57 |
58 | // confirm we received an OK status
59 | if resp.StatusCode != http.StatusOK {
60 | log.Fatalln("Error Status not OK:", resp.StatusCode)
61 | }
62 |
63 | // read the entire body of the response
64 | body, err := ioutil.ReadAll(resp.Body)
65 | if err != nil {
66 | log.Fatalln("Error reading body:", err)
67 | }
68 |
69 | // create an empty instance of Feed struct
70 | // this is what gets filled in when unmarshaling JSON
71 | var entries Feed
72 | if err := json.Unmarshal(body, &entries); err != nil {
73 | log.Fatalln("Error decoing JSON", err)
74 | }
75 |
76 | // loop through the children and create entry objects
77 | for _, ed := range entries.Data.Children {
78 | entry := ed.Data
79 | log.Println(">>>")
80 | log.Println("Title :", entry.Title)
81 | log.Println("Author :", entry.Author)
82 | log.Println("URL :", entry.URL)
83 | log.Printf("Comments: http://reddit.com%s \n", entry.Permalink)
84 | }
85 | }
86 | ```
87 |
88 |
--------------------------------------------------------------------------------
/pages/slices.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Slices
3 | layout: page
4 | order: 3
5 | ---
6 |
7 | # Working with Slices
8 |
9 | Go has an array type, but it has a fixed size. Slices in Go are dynamically-sized and more flexible. Slices are the common data type you will work with.
10 |
11 | The specification for slices are `[]T` where T is the type, for example `[]string` is a set of strings, or `[]int` is a set of integers.
12 |
13 | ## Initialize
14 |
15 | Initialize an empty slice.
16 |
17 | ```go
18 | var empty []int
19 | ```
20 |
21 | Initialize a slice with values.
22 |
23 | ```go
24 | alphas := []string{"abc", "def", "ghi", "jkl"}
25 | ```
26 |
27 | ## Append
28 |
29 | Slices can not be modified, a new copy needs to be made, it is common to copy to the same variable.
30 |
31 | ```go
32 | var nums []int
33 | nums = append(nums, 203)
34 | nums = append(nums, 302)
35 | fmt.Println(nums)
36 | // [203 302]
37 | ```
38 |
39 | Append multiple values at once.
40 |
41 | ```go
42 | alphas := []string{"abc", "def", "ghi", "jkl"}
43 | alphas = append(alphas, "mno", "pqr", "stu")
44 | ```
45 |
46 | ## Common Array Operations
47 |
48 | Get length of a slice.
49 |
50 | ```go
51 | fmt.Println("Length: ", len(alphas))
52 | ```
53 |
54 | Retrieve a single element from slice
55 |
56 | ```go
57 | fmt.Println(alphas[1])
58 | ```
59 |
60 | Retrieve a slice of a slice
61 |
62 | ```go
63 | alpha2 := alphas[1:3]
64 | fmt.Println(alpha2)
65 | ```
66 |
67 |
68 | ## Element Exists in a Slice
69 |
70 | There is no built-in function to determine if an element exists in a slice. Here is an example function to check if a string exists in an array of strings.
71 |
72 | ```go
73 | package main
74 |
75 | import "fmt"
76 |
77 | func main() {
78 |
79 | alphas := []string{"abc", "def", "ghi", "jkl"}
80 |
81 | if elemExists("def", alphas) {
82 | fmt.Println("Exists!")
83 | }
84 | }
85 |
86 | func elemExists(s string, a []string) bool {
87 | for _, v := range a {
88 | if v == s {
89 | return true
90 | }
91 | }
92 | return false
93 | }
94 | ```
95 |
96 |
--------------------------------------------------------------------------------
/pages/sorting.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Sorting
3 | layout: page
4 | order: 15
5 | ---
6 |
7 | # Sorting Arrays and Maps
8 |
9 | The [`sort`](https://golang.org/pkg/sort/) standard library is used for sorting slices, maps, and user define collections.
10 |
11 | ## Sort Alphabetical
12 |
13 | Use `sort.Strings()` to sort alphabetically
14 |
15 | ```go
16 | abc := []string{"jkl", "ghi", "abc", "def"}
17 | sort.Strings(abc)
18 | fmt.Println("Sorted ABC:", abc)
19 | ```
20 |
21 | ## Sort Numeric
22 |
23 | Use `sort.Ints()` to sort numerically
24 |
25 | ```go
26 | nums := []int{4, 2, 12, 5, 1, 3}
27 | sort.Ints(nums)
28 | fmt.Println("Sorted Nums:", nums)
29 | ```
30 |
31 | ## Reverse Sort
32 |
33 | Reverse sort, need to cast `abc` as a StringSlice to reverse and sort
34 |
35 | ```go
36 | sort.Sort(sort.Reverse(sort.StringSlice(abc)))
37 | fmt.Println("Reverse ABC:", abc)
38 | ```
39 |
40 | ## Sort Maps
41 |
42 | To sort a map by keys, pull an array of keys out of the map, sort the keys and then iterate over the sorted keys. A map by itself is not sortable.
43 |
44 | ```go
45 | hash := map[string]int{
46 | "c": 3,
47 | "a": 1,
48 | "b": 2,
49 | "e": 5,
50 | "d": 4,
51 | }
52 |
53 | // Create array of kys
54 | var keys []string
55 | for k := range hash {
56 | keys = append(keys, k)
57 | }
58 |
59 | // Sort keys
60 | sort.Strings(keys)
61 |
62 | // Use ordered keys to loop through hash
63 | for i := range keys {
64 | fmt.Printf("%s => %v\n", keys[i], hash[keys[i]])
65 | }
66 | ```
67 |
--------------------------------------------------------------------------------
/pages/strings.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Strings
3 | layout: page
4 | order: 2
5 | ---
6 |
7 | # Working with Strings
8 |
9 | A set of examples working with strings in Golang. The `strings` standard library contains most of the functions you'll use to work with string. See [strings package](http://golang.org/pkg/strings/) documentation
10 |
11 | Create and set a variable in one line using `:=` operator. Go will automatically determine the type by the assignment.
12 |
13 | ```go
14 | str := "This is an example string"
15 | ```
16 |
17 | In general, Go does not use a standard object oriented notation to operate on values. This differs from languages like JavaScript and Python. Instead in Go, you typically pass in the variable you are working on to the function. Here is an example using the `Contains` function from the `strings` package:
18 |
19 | ```go
20 | exists := strings.Contains(str, "example")
21 | ```
22 | Here is a full example program, that uses the `ToLower` function to convert a string to lowercase, and `Contains` to check if a string contains another.
23 |
24 | ```go
25 | package main
26 |
27 | import (
28 | "fmt" // for standard output
29 | "strings" // for manipulating strings
30 | )
31 |
32 | func main() {
33 |
34 | // create a string variable
35 | str := "HI, I'M UPPER CASE"
36 |
37 | // convert to lower case
38 | lower := strings.ToLower(str)
39 |
40 | // output to show its really lower case
41 | fmt.Println(lower)
42 |
43 | // check if string contains another string
44 | if strings.Contains(lower, "case") {
45 | fmt.Println("Yes, exists!")
46 | }
47 | }
48 | ```
49 |
50 | ## Strings as Array of Characters
51 |
52 | Strings in Go are an array of characters and can be referenced as such.
53 |
54 | ```go
55 | str := "abcdefghijklmnopqrstuvwxyz"
56 | fmt.Println("Chars 3-10: " + str[3:10])
57 |
58 | // printing out first 5 characters
59 | fmt.Println("First Five: " + str[:5])
60 |
61 | // printing out from 13 to end
62 | fmt.Println("From 13 on: " + str[13:])
63 | ```
64 |
65 | 💡 The Go Playground is a useful online environment that runs Go code in your browser. See the above example in the Go Playground here: [https://play.golang.org/p/DC7R7XKzZ5G](https://play.golang.org/p/DC7R7XKzZ5G). I often use the playground to test out a bit of logic I'm working on.
66 |
67 | ## Split Strings
68 |
69 | Split a string on a specific character or word
70 |
71 | ```go
72 | sentence := "I'm a sentence made up of words"
73 | words := strings.Split(sentence, " ")
74 | fmt.Printf("%v \n", words)
75 | ```
76 |
77 | If you were splitting on whitespace, using Fields is better because it will split on all whitespace characters, not just a space.
78 |
79 | ```go
80 | sentence := "I'm a sentence made up of words"
81 | fields := strings.Fields(sentence)
82 | fmt.Printf("%v \n", fields)
83 | ```
84 |
85 | ## Join an Array of Strings
86 |
87 | In an OOP world, the `Join` function would be defined in an array package. In Go, however, it is part of the strings package, you pass in an array of strings and the separator you want to join them.
88 |
89 | ```go
90 | lines := []string{ "one", "two", "three" }
91 | str := string.Join(lines, ",")
92 | fmt.Println(str)
93 | >> one, two, three
94 | ```
95 |
96 | ## String Replace
97 |
98 | To replace a string with another use `strings.Replace`
99 |
100 | ```go
101 | str := "The blue whale loves blue fish."
102 | newstr := strings.Replace(str, "blue", "red", 1)
103 | >> "The red whale loves blue fish."
104 | ```
105 |
106 | The `strings.Replace` function requires passing in how many replacements it should do. Pass in `-1` to replace all occurrences.
107 |
108 | ```go
109 | str := "The blue whale loves blue fish."
110 | newstr := strings.Replace(str, "blue", "red", -1)
111 | >> "The red whale loves red fish."
112 | ```
113 |
114 | Go version 1.12 introduced the `strings.ReplaceAll` function that does not have the fourth argument -- it, as it says, replaces all occurrences.
115 |
116 |
117 | ## Strings HasPrefix and HasSuffix
118 |
119 | The Go functions for checking if a strings starts with, or ends with, another string are `strings.HasPrefix()` and `strings.HasSuffix()`.
120 |
121 | ```go
122 | path := "/home/mkaz"
123 | isAbsolute := strings.HasPrefix(path, "/")
124 |
125 | dir := "/home/mkaz/"
126 | hasTrailingSlash := strings.HasSuffix(path, "/")
127 | ```
128 |
129 |
--------------------------------------------------------------------------------
/pages/structs.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Structs
3 | layout: page
4 | order: 7
5 | ---
6 |
7 | # Working with Structs
8 |
9 | A struct is a data type in Go that is a collection of fields. A struct is the closest Go gets to objects.
10 |
11 | ## Define Struct
12 |
13 | ```go
14 | // define Dog struct
15 | type Dog struct {
16 | Name string
17 | Color string
18 | }
19 | ```
20 |
21 | ## Create Instance
22 |
23 | Create an instance of a struct type
24 |
25 | ```go
26 | Spot := Dog{Name: "Spot", Color: "brown"}
27 | ```
28 |
29 | An alternative way, create a blank instance, each field is set to its zero value. Access struct fields using dot notation for getting or setting.
30 |
31 | ```go
32 | var Rover Dog
33 | Rover.Name = "Rover"
34 | Rover.Color = "light tan with dark patches"
35 | ```
36 |
37 |
--------------------------------------------------------------------------------
/pages/testing.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Testing
3 | layout: page
4 | order: 24
5 | ---
6 |
7 | # Testing
8 |
9 | The [Go testing package](https://golang.org/pkg/testing/) supports creating unit test in go. Your test code is written in plain go, there is not a new assert language or syntax to learn. Write go code and use `t.Fail` or `t.Error` to signal the test did not pass.
10 |
11 | To write a new test create a test file, ending in `_test.go` that includes functions with the following signature: `func TestXxx(*testing.T)`
12 |
13 | Note: The function name must start with `Test` and include a capitalized second part to identify the test routing.
14 |
15 | For example, if you want to test an `Add` function in your project:
16 |
17 | Create `add_test.go`:
18 |
19 | ```go
20 | package main
21 |
22 | import "testing"
23 |
24 | func TestAdd(t *testing.T) {
25 | sum := Add(1, 1)
26 | if sum != 2 {
27 | t.Errorf("Expected %d => Received %d", 2, sum)
28 | }
29 | }
30 | ```
31 |
32 | Run test using: `go test`
33 |
34 | ## Test Table
35 |
36 | Use a table structure to setup and test multiple inputs and expected values.
37 |
38 | ```go
39 | func TestAdd(t *testing.T) {
40 | var testData = []struct {
41 | param1 int
42 | param2 int
43 | expect int
44 | }{
45 | { 1, 2, 3 },
46 | { 0, 1, 1 },
47 | { 1, 0, 1 },
48 | { -1, 1, 0 },
49 | { -1, -1, -2 },
50 | }
51 |
52 | for _, td := range testData {
53 | result := Add(td.param1, td.param2)
54 | if td.expect != result {
55 | t.Errorf("Expected %s but received %s", td.expect, result)
56 | }
57 | }
58 | }
59 | ```
60 |
61 |
62 |
--------------------------------------------------------------------------------
/pages/web-server.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Web Server
3 | layout: page
4 | order: 17
5 | ---
6 |
7 | # Web Server
8 |
9 | The standard library [`net/http `](https://golang.org/pkg/net/http/) provides a powerful set of tools you can use to make your own web server.
10 |
11 | See my Lanyon project: [https://github.com/mkaz/lanyon](https://github.com/mkaz/lanyon) for a more complete server created in Go which converts markdown to html.
12 |
13 | ```go
14 | package main
15 |
16 | import (
17 | "fmt"
18 | "log"
19 | "net/http"
20 | )
21 |
22 | func main() {
23 | // associate URLs requested to functions that handle requests
24 | http.HandleFunc("/hello", helloRequest)
25 | http.HandleFunc("/", getRequest)
26 |
27 | // start web server
28 | log.Println("Listening on http://localhost:9999/")
29 | log.Fatal(http.ListenAndServe(":9999", nil))
30 | }
31 |
32 | // basic handler for /hello request
33 | func helloRequest(w http.ResponseWriter, r *http.Request) {
34 |
35 | // Fprint writes to a writer, in this case the http response
36 | fmt.Fprint(w, "Hallo Welt")
37 | return
38 | }
39 |
40 | // this function simply serves up the file requested, or
41 | // an index list if a directory is requested
42 | func getRequest(w http.ResponseWriter, r *http.Request) {
43 | file_requested := "./" + r.URL.Path
44 | http.ServeFile(w, r, file_requested)
45 | return
46 | }
47 | ```
48 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 |
2 | # Working with Go
3 |
4 | ## View online at: https://mkaz.blog/working-with-go/
5 |
6 | Working with Go is a set of examples for Go (golang) to help an experienced programmer become familiar with the Go language. Go is often referred to as golang to help searches.
7 |
8 |
9 | ## Resources
10 |
11 | This set of examples assumes a base level of programming experience and is intended for someone learning the Go language from another language; not necessarily someone new to programming altogether.
12 |
13 | If you are starting out and want to learn how to program and choose Go as your first language, check out [Learn Programming in Go](http://www.golang-book.com/)
14 |
15 | The official site has a [Tour of Go](http://tour.golang.org/) which is an interactive walk through, another good introduction to the language.
16 |
17 | I'm also a big fan of [Go by Example](https://gobyexample.com/) which is quite similar.
18 |
19 |
20 | ## Contribute
21 |
22 | The site is sourced from markdown files in the `pages` directory. Any additions, corrections, suggestions or any contributions are appreciated.
23 |
24 | To submit a pull request, make your edit to the file in `pages` directory.
25 |
26 | Working with Go was started by Marcus Kazmierczak. Thanks to all the contributors who have helped make it even better.
27 |
28 |
29 | ## License
30 |
31 | Working with Go is licensed under a Creative Commons Attribution 4.0 International License.
32 |
--------------------------------------------------------------------------------