Episode Post & Video Links: 1, 2 (this post), 3, 4, 5, 6, 7, and 8. Non-linked are in the works! Videos available now on Youtube however, so check em’ out!
In episode two I went over a lot of the material that I covered in the first episode, but added more context, historical reasons certain things are the way they are in Go and the stack, and went over a number of new elements of information too. One thing I got further into this episode is the package and dependency management with Go Dep and also how to create a package, or dependency library for use in other Go libraries or applications. It’s just a small introduction in this episode, but pivotal to future episodes, as I’ll be jumping further into library creation and related details.
In this post I’ve got the time point breakdown like usual, but also a few additional bits of information and code examples, plus links to the repository I’ve setup for this particular episode. The quick links to those references are below, and also I’ll link at particular call out points within the time points.
Quick Links:
- Episode 2 Repository
- Github: https://github.com/golang/go
- Golang: https://golang.org
- “The Go Programming Language” by Alan A. A. Donovan and Brian W. Kernighan
Key Topics Covered
Data Types, Packages, and Dependency Management
2:52 – Fumbling through getting started. It is after all Saturday morning!
3:00 – Recap of what we covered in the first session. Includes a quick review of the previous session code too, such as the random data generation library we setup and used.
6:40 – Covering some specifics of the IDE’s, the stories of the benefits of Go having a specific and somewhat detailed convention to the way syntax, variables, and related features are used.
7:40 – Covering gofmt
and what it gives us.
9:45 – Looking at the gofmt
plugins and IDE features around the conventions.
14:06 – New example time! In this one, I work through an example showing how to find duplicate lines in passed in text.
Duplicate Line Finder
I went through the various steps of creating the code, but then took a little bit of a detour from the example in the book. Instead of lines by the CLI it takes in content from a text file. The code in main.go ended up like this.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bufio" | |
"fmt" | |
"os" | |
) | |
func main() { | |
counts := make(map[string]int) | |
files := os.Args[1:] | |
if len(files) == 0 { | |
countLines(os.Stdin, counts) | |
} else { | |
for _, arg := range files { | |
f, err := os.Open(arg) | |
if err != nil { | |
fmt.Printf("The Error Happened! %s", os.Stderr) | |
continue | |
} | |
countLines(f, counts) | |
errFile := f.Close() | |
if errFile != nil { | |
fmt.Println("Holy moley the file didn't close correctly!") | |
} | |
} | |
} | |
for line, n := range counts { | |
if n > 1 { | |
fmt.Printf("%d\t%s\n", n, line) | |
} | |
} | |
} | |
func countLines(f *os.File, counts map[string]int) { | |
input := bufio.NewScanner(f) | |
for input.Scan() { | |
counts[input.Text()]++ | |
} | |
} |
Then if you’d like to check out the text file and remaining content in that project, check out the master branch of the episode 2 repo.
36:34 – Here I take a thorough step through committing this project to github, which is the included repo in this post. However I step through the interface of using Jetbrains Goland to do the commit, how it enables gofmt
and other features to improve the condition of code and ensure it meets linter demands and related crtieria. I also cover the .gitignore file and other elements to create a usable repository.
44:30 – Setting up the repository for today’s code at https://github.com/Adron/learning-go-…
50:00 – Setup of the key again for using Github. How to setup your ssh keys using ssh-keygen.
56:00 – Going beyond just the language, and building out a Go build on Travis CI.
1:10:16 – Creating a new branch for the next code examples and topics. At this point I shift into type declarations. Working through some constants, very basic function declarations, and related capabilities to calculate temperatures between Fahrenheit and Celsius.
The tempApp Branch is available in the repository here.
At this point I shift into type declarations. Working through some constants, very basic function declarations, and related capabilities to calculate temperatures between Fahrenheit and Celsius.
During this point, we take a look at our first package. This package ended up looking like this.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package tempconv | |
type Celsius float64 | |
type Fahrenheit float64 | |
const ( | |
AbsoluteZeroC Celsius = –273.15 | |
FreezingC Celsius = 0 | |
BoilingC Celsius = 100 | |
) | |
func CelsiusToFahrenheit(c Celsius) Fahrenheit { | |
return Fahrenheit(c*9/5 + 32) | |
} | |
func FahrenheitToCelsius(f Fahrenheit) Celsius { | |
return Celsius((f – 32) * 5 / 9) | |
} |
In the main.go file, I showed how you can use this package by adding a respective import shown in this code.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
tempconv "github.com/Adron/awesomeProject/tempconv" | |
) | |
func main() { | |
fmt.Println("Temperatures are hard to figure off the top of one's mind!") | |
boilingF := tempconv.CelsiusToFahrenheit(BoilingC) | |
fmt.Printf("%v\n", boilingF) | |
fmt.Printf("%s\n", boilingF) | |
fmt.Println(boilingF) | |
fmt.Printf("%g\n", boilingF) | |
} |
1:17:54 – At this point, to increase readability of font sizes I get into the various Goland IDE options.
1:38:12 – Creating the final branch for this session to pull in a public package and use it in project. For this, I pull in a random data generation package to use in some application code.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
randomdata "github.com/Pallinder/go-randomdata" | |
) | |
func main() { | |
// Print a random silly name | |
fmt.Println(randomdata.SillyName()) | |
// Print a male title | |
fmt.Println(randomdata.Title(randomdata.Male)) | |
// Print a female title | |
fmt.Println(randomdata.Title(randomdata.Female)) | |
// Print a title with random gender | |
fmt.Println(randomdata.Title(randomdata.RandomGender)) | |
// Print a male first name | |
fmt.Println(randomdata.FirstName(randomdata.Male)) | |
// Print a female first name | |
fmt.Println(randomdata.FirstName(randomdata.Female)) | |
// Print a last name | |
fmt.Println(randomdata.LastName()) | |
// Print a male name | |
fmt.Println(randomdata.FullName(randomdata.Male)) | |
// Print a female name | |
fmt.Println(randomdata.FullName(randomdata.Female)) | |
// Print a name with random gender | |
fmt.Println(randomdata.FullName(randomdata.RandomGender)) | |
// Print an email | |
fmt.Println(randomdata.Email()) | |
// Print a country with full text representation | |
fmt.Println(randomdata.Country(randomdata.FullCountry)) | |
// Print a country using ISO 3166-1 alpha-2 | |
fmt.Println(randomdata.Country(randomdata.TwoCharCountry)) | |
// Print a country using ISO 3166-1 alpha-3 | |
fmt.Println(randomdata.Country(randomdata.ThreeCharCountry)) | |
// Print BCP 47 language tag | |
fmt.Println(randomdata.Locale()) | |
// Print a currency using ISO 4217 | |
fmt.Println(randomdata.Currency()) | |
// Print the name of a random city | |
fmt.Println(randomdata.City()) | |
// Print the name of a random american state | |
fmt.Println(randomdata.State(randomdata.Large)) | |
// Print the name of a random american state using two chars | |
fmt.Println(randomdata.State(randomdata.Small)) | |
// Print an american sounding street name | |
fmt.Println(randomdata.Street()) | |
// Print an american sounding address | |
fmt.Println(randomdata.Address()) | |
// Print a random number >= 10 and < 20 | |
fmt.Println(randomdata.Number(10, 20)) | |
// Print a number >= 0 and < 20 | |
fmt.Println(randomdata.Number(20)) | |
// Print a random float >= 0 and < 20 with decimal point 3 | |
fmt.Println(randomdata.Decimal(0, 20, 3)) | |
// Print a random float >= 10 and < 20 | |
fmt.Println(randomdata.Decimal(10, 20)) | |
// Print a random float >= 0 and < 20 | |
fmt.Println(randomdata.Decimal(20)) | |
// Print a bool | |
fmt.Println(randomdata.Boolean()) | |
// Print a paragraph | |
fmt.Println(randomdata.Paragraph()) | |
// Print a postal code | |
fmt.Println(randomdata.PostalCode("SE")) | |
// Print a set of 2 random numbers as a string | |
fmt.Println(randomdata.StringNumber(2, "-")) | |
// Print a set of 2 random 3-Digits numbers as a string | |
fmt.Println(randomdata.StringNumberExt(2, "-", 3)) | |
// Print a random string sampled from a list of strings | |
fmt.Println(randomdata.StringSample("my string 1", "my string 2", "my string 3")) | |
// Print a valid random IPv4 address | |
fmt.Println(randomdata.IpV4Address()) | |
// Print a valid random IPv6 address | |
fmt.Println(randomdata.IpV6Address()) | |
// Print a browser's user agent string | |
fmt.Println(randomdata.UserAgentString()) | |
// Print a day | |
fmt.Println(randomdata.Day()) | |
// Print a month | |
fmt.Println(randomdata.Month()) | |
// Print full date like Monday 22 Aug 2016 | |
fmt.Println(randomdata.FullDate()) | |
// Print full date <= Monday 22 Aug 2016 | |
fmt.Println(randomdata.FullDateInRange("2016-08-22")) | |
// Print full date >= Monday 01 Aug 2016 and <= Monday 22 Aug 2016 | |
fmt.Println(randomdata.FullDateInRange("2016-08-01", "2016-08-22")) | |
// Print phone number according to e.164 | |
fmt.Println(randomdata.PhoneNumber()) | |
// Get a complete and randomised profile of data generally used for users | |
// There are many fields in the profile to use check the Profile struct definition in fullprofile.go | |
profile := randomdata.GenerateProfile(randomdata.Male | randomdata.Female | randomdata.RandomGender) | |
fmt.Printf("The new profile's username is: %s and password (md5): %s\n", profile.Login.Username, profile.Login.Md5) | |
// Get a random country-localised street name for Great Britain | |
fmt.Println(randomdata.StreetForCountry("GB")) | |
// Get a random country-localised street name for USA | |
fmt.Println(randomdata.StreetForCountry("US")) | |
// Get a random country-localised province for Great Britain | |
fmt.Println(randomdata.ProvinceForCountry("GB")) | |
// Get a random country-localised province for USA | |
fmt.Println(randomdata.ProvinceForCountry("US")) | |
} |
1:44:50 – Further discussion and explanation of what to include in .gitignore files to manage projects, but also what is and isn’t included for dependencies and other details around all of this.
2:13:22 – The wicked awesome hacker outtro.